From 283fce21c13672b609664a88e2575aaae16a7ddb Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Tue, 27 Feb 2024 12:32:21 -0500 Subject: [PATCH] x/tools: drop go1.18 support Updates golang/go#64407 Change-Id: I247a7ff7f07613674f8e31e4cb9c5a68762d2203 Reviewed-on: https://go-review.googlesource.com/c/tools/+/567418 Reviewed-by: Robert Findley Auto-Submit: Alan Donovan LUCI-TryBot-Result: Go LUCI --- cmd/bisect/main_test.go | 3 +- copyright/copyright.go | 3 - copyright/copyright_test.go | 3 - go.mod | 2 +- go/analysis/passes/asmdecl/arches_go118.go | 12 - go/analysis/passes/asmdecl/arches_go119.go | 14 - go/analysis/passes/asmdecl/asmdecl.go | 3 +- .../testdata/src/typeparams/typeparams.go | 2 - .../src/typeparams/typeparams.go.golden | 2 - .../testdata/src/typeparams/typeparams.go | 2 - .../composite/testdata/src/a/a_fuzz_test.go | 3 - .../testdata/src/a/a_fuzz_test.go.golden | 3 - .../testdata/src/typeparams/typeparams.go | 2 - .../passes/loopclosure/loopclosure_test.go | 2 - .../testdata/src/typeparams/typeparams.go | 2 +- .../testdata/src/versions/go18.txtar | 6 +- .../testdata/src/versions/go22.txtar | 3 + .../testdata/src/typeparams/typeparams.go | 4 +- .../testdata/src/typeparams/typeparams.go | 8 +- .../passes/nilness/nilness_go117_test.go | 20 - go/analysis/passes/nilness/nilness_test.go | 5 + go/analysis/passes/printf/printf_test.go | 3 - .../testdata/src/typeparams/diagnostics.go | 3 - .../testdata/src/typeparams/wrappers.go | 3 - .../passes/stdmethods/testdata/src/a/b.go | 3 - go/analysis/passes/testinggoroutine/util.go | 2 +- .../passes/tests/testdata/src/a/go118_test.go | 3 - .../testdata/src/typeparams/typeparams.go | 2 - .../src/typeparams/userdefs/userdefs.go | 4 +- go/analysis/unitchecker/separate_test.go | 2 - go/analysis/unitchecker/unitchecker_test.go | 2 - go/callgraph/rta/rta.go | 3 +- go/callgraph/vta/vta_go117_test.go | 33 -- go/callgraph/vta/vta_test.go | 17 + go/packages/packages_test.go | 3 - go/ssa/builder_test.go | 4 - go/ssa/interp/interp_test.go | 4 - go/types/internal/play/play.go | 2 - go/types/objectpath/objectpath_go118_test.go | 3 - godoc/godoc.go | 9 +- godoc/tohtml_go119.go | 17 - godoc/tohtml_other.go | 17 - gopls/api-diff/api_diff.go | 3 - gopls/go.mod | 2 +- .../analysis/deprecated/deprecated_test.go | 2 - .../testdata/src/typeparams/typeparams.go | 3 - .../src/typeparams/typeparams.go.golden | 3 - gopls/internal/cache/port_test.go | 6 +- gopls/internal/cmd/serve.go | 5 +- gopls/internal/golang/comment.go | 395 ++---------------- gopls/internal/golang/comment_go118_test.go | 371 ---------------- gopls/internal/golang/comment_go119.go | 54 --- gopls/internal/golang/origin.go | 20 +- gopls/internal/golang/origin_119.go | 33 -- gopls/internal/golang/rename.go | 23 +- gopls/internal/protocol/generate/generate.go | 3 - gopls/internal/protocol/generate/main.go | 3 - gopls/internal/protocol/generate/main_test.go | 3 - gopls/internal/protocol/generate/output.go | 3 - gopls/internal/protocol/generate/tables.go | 3 - gopls/internal/protocol/generate/typenames.go | 3 - gopls/internal/protocol/generate/types.go | 3 - gopls/internal/protocol/protocol.go | 4 +- gopls/internal/server/command.go | 10 +- gopls/internal/server/general.go | 47 ++- gopls/internal/server/prompt.go | 2 +- gopls/internal/telemetry/telemetry.go | 107 ----- gopls/internal/telemetry/telemetry_go118.go | 42 -- .../completion/completion18_test.go | 3 - .../integration/misc/configuration_test.go | 15 +- .../test/integration/misc/vuln_test.go | 9 +- gopls/internal/test/marker/marker_test.go | 15 +- .../test/marker/testdata/definition/embed.txt | 5 - .../marker/testdata/definition/import.txt | 5 - .../test/marker/testdata/definition/misc.txt | 5 - .../testdata/diagnostics/issue60544.txt | 4 - .../testdata/diagnostics/rundespiteerrors.txt | 3 - .../test/marker/testdata/hover/basiclit.txt | 5 - .../test/marker/testdata/hover/const.txt | 5 - .../test/marker/testdata/hover/godef.txt | 3 + .../test/marker/testdata/hover/goprivate.txt | 5 - .../test/marker/testdata/hover/hover.txt | 5 - .../test/marker/testdata/hover/linkable.txt | 5 - .../testdata/hover/linkable_generics.txt | 5 - .../test/marker/testdata/hover/linkname.txt | 5 - .../test/marker/testdata/hover/std.txt | 5 - .../test/marker/testdata/symbol/generic.txt | 3 - gopls/internal/util/bug/bug.go | 4 +- gopls/internal/util/frob/frob.go | 43 +- gopls/internal/util/lru/lru_fuzz_test.go | 3 - gopls/internal/util/slices/slices.go | 10 +- gopls/internal/vulncheck/scan/command.go | 3 - gopls/internal/vulncheck/semver/semver.go | 3 - .../internal/vulncheck/semver/semver_test.go | 3 - gopls/internal/vulncheck/vulntest/db.go | 3 - gopls/internal/vulncheck/vulntest/db_test.go | 3 - gopls/internal/vulncheck/vulntest/report.go | 3 - .../vulncheck/vulntest/report_test.go | 3 - gopls/internal/vulncheck/vulntest/stdlib.go | 3 - .../vulncheck/vulntest/stdlib_test.go | 3 - gopls/main.go | 4 +- internal/compat/appendf.go | 13 - internal/compat/appendf_118.go | 13 - internal/compat/doc.go | 7 - internal/gcimporter/gcimporter_test.go | 22 +- internal/gcimporter/iexport_go118_test.go | 5 +- internal/gcimporter/support_go117.go | 16 - internal/gcimporter/support_go118.go | 3 - internal/gcimporter/unified_no.go | 4 +- internal/gcimporter/unified_yes.go | 4 +- internal/gcimporter/ureader_no.go | 19 - internal/gcimporter/ureader_yes.go | 3 - internal/imports/mod_test.go | 8 - internal/robustio/robustio_posix.go | 2 - internal/tokeninternal/tokeninternal.go | 28 +- internal/typeparams/common.go | 18 +- internal/typeparams/common_test.go | 5 - internal/typesinternal/types_118.go | 3 - 118 files changed, 186 insertions(+), 1584 deletions(-) delete mode 100644 go/analysis/passes/asmdecl/arches_go118.go delete mode 100644 go/analysis/passes/asmdecl/arches_go119.go delete mode 100644 go/analysis/passes/nilness/nilness_go117_test.go delete mode 100644 go/callgraph/vta/vta_go117_test.go delete mode 100644 godoc/tohtml_go119.go delete mode 100644 godoc/tohtml_other.go delete mode 100644 gopls/internal/golang/comment_go118_test.go delete mode 100644 gopls/internal/golang/comment_go119.go delete mode 100644 gopls/internal/golang/origin_119.go delete mode 100644 gopls/internal/telemetry/telemetry.go delete mode 100644 gopls/internal/telemetry/telemetry_go118.go delete mode 100644 internal/compat/appendf.go delete mode 100644 internal/compat/appendf_118.go delete mode 100644 internal/compat/doc.go delete mode 100644 internal/gcimporter/support_go117.go delete mode 100644 internal/gcimporter/ureader_no.go diff --git a/cmd/bisect/main_test.go b/cmd/bisect/main_test.go index 7c10ff0fb4b..bff1bf23c0c 100644 --- a/cmd/bisect/main_test.go +++ b/cmd/bisect/main_test.go @@ -17,7 +17,6 @@ import ( "testing" "golang.org/x/tools/internal/bisect" - "golang.org/x/tools/internal/compat" "golang.org/x/tools/internal/diffp" "golang.org/x/tools/txtar" ) @@ -82,7 +81,7 @@ func Test(t *testing.T) { have[color] = true } if m.ShouldReport(uint64(i)) { - out = compat.Appendf(out, "%s %s\n", color, bisect.Marker(uint64(i))) + out = fmt.Appendf(out, "%s %s\n", color, bisect.Marker(uint64(i))) } } err = nil diff --git a/copyright/copyright.go b/copyright/copyright.go index b13b56e85f1..556c6e4f69a 100644 --- a/copyright/copyright.go +++ b/copyright/copyright.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - // Package copyright checks that files have the correct copyright notices. package copyright diff --git a/copyright/copyright_test.go b/copyright/copyright_test.go index 7f7892524f5..947fb10c1d1 100644 --- a/copyright/copyright_test.go +++ b/copyright/copyright_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package copyright import ( diff --git a/go.mod b/go.mod index c8e522063d4..9458c1500cc 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module golang.org/x/tools -go 1.18 +go 1.19 require ( github.com/yuin/goldmark v1.4.13 diff --git a/go/analysis/passes/asmdecl/arches_go118.go b/go/analysis/passes/asmdecl/arches_go118.go deleted file mode 100644 index d8211afdc8d..00000000000 --- a/go/analysis/passes/asmdecl/arches_go118.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2022 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. - -//go:build !go1.19 -// +build !go1.19 - -package asmdecl - -func additionalArches() []*asmArch { - return nil -} diff --git a/go/analysis/passes/asmdecl/arches_go119.go b/go/analysis/passes/asmdecl/arches_go119.go deleted file mode 100644 index 3018383e7f2..00000000000 --- a/go/analysis/passes/asmdecl/arches_go119.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2022 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. - -//go:build go1.19 -// +build go1.19 - -package asmdecl - -var asmArchLoong64 = asmArch{name: "loong64", bigEndian: false, stack: "R3", lr: true} - -func additionalArches() []*asmArch { - return []*asmArch{&asmArchLoong64} -} diff --git a/go/analysis/passes/asmdecl/asmdecl.go b/go/analysis/passes/asmdecl/asmdecl.go index e24dac9865a..f2ca95aa9eb 100644 --- a/go/analysis/passes/asmdecl/asmdecl.go +++ b/go/analysis/passes/asmdecl/asmdecl.go @@ -96,6 +96,7 @@ var ( asmArchRISCV64 = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true, retRegs: []string{"X10", "F10"}} asmArchS390X = asmArch{name: "s390x", bigEndian: true, stack: "R15", lr: true} asmArchWasm = asmArch{name: "wasm", bigEndian: false, stack: "SP", lr: false} + asmArchLoong64 = asmArch{name: "loong64", bigEndian: false, stack: "R3", lr: true} arches = []*asmArch{ &asmArch386, @@ -111,11 +112,11 @@ var ( &asmArchRISCV64, &asmArchS390X, &asmArchWasm, + &asmArchLoong64, } ) func init() { - arches = append(arches, additionalArches()...) for _, arch := range arches { arch.sizes = types.SizesFor("gc", arch.name) if arch.sizes == nil { diff --git a/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go b/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go index 345db277933..fc80410e78a 100644 --- a/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go +++ b/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go @@ -4,8 +4,6 @@ // This file contains tests for the useless-assignment checker. -//go:build go1.18 - package testdata import "math/rand" diff --git a/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go.golden b/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go.golden index d9384ed5aab..8c8c4b61f5c 100644 --- a/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go.golden +++ b/go/analysis/passes/assign/testdata/src/typeparams/typeparams.go.golden @@ -4,8 +4,6 @@ // This file contains tests for the useless-assignment checker. -//go:build go1.18 - package testdata import "math/rand" diff --git a/go/analysis/passes/bools/testdata/src/typeparams/typeparams.go b/go/analysis/passes/bools/testdata/src/typeparams/typeparams.go index 718462593a1..3afb56a5d0c 100644 --- a/go/analysis/passes/bools/testdata/src/typeparams/typeparams.go +++ b/go/analysis/passes/bools/testdata/src/typeparams/typeparams.go @@ -4,8 +4,6 @@ // This file contains tests for the bool checker. -//go:build go1.18 - package typeparams type T[P interface{ ~int }] struct { diff --git a/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go b/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go index 20b652e88dd..00cbd70051e 100644 --- a/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go +++ b/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package a import "testing" diff --git a/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go.golden b/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go.golden index 20b652e88dd..00cbd70051e 100644 --- a/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go.golden +++ b/go/analysis/passes/composite/testdata/src/a/a_fuzz_test.go.golden @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package a import "testing" diff --git a/go/analysis/passes/httpresponse/testdata/src/typeparams/typeparams.go b/go/analysis/passes/httpresponse/testdata/src/typeparams/typeparams.go index 65dd58c7f8a..b2515c950ba 100644 --- a/go/analysis/passes/httpresponse/testdata/src/typeparams/typeparams.go +++ b/go/analysis/passes/httpresponse/testdata/src/typeparams/typeparams.go @@ -4,8 +4,6 @@ // This file contains tests for the httpresponse checker. -//go:build go1.18 - package typeparams import ( diff --git a/go/analysis/passes/loopclosure/loopclosure_test.go b/go/analysis/passes/loopclosure/loopclosure_test.go index c8aab4834d3..683f91e7b73 100644 --- a/go/analysis/passes/loopclosure/loopclosure_test.go +++ b/go/analysis/passes/loopclosure/loopclosure_test.go @@ -33,8 +33,6 @@ func TestVersions22(t *testing.T) { } func TestVersions18(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - testfile := filepath.Join(analysistest.TestData(), "src", "versions", "go18.txtar") runTxtarFile(t, testfile, loopclosure.Analyzer, "golang.org/fake/versions") } diff --git a/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go b/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go index ef5b143f6da..85976873b9a 100644 --- a/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go +++ b/go/analysis/passes/loopclosure/testdata/src/typeparams/typeparams.go @@ -5,7 +5,7 @@ // This file contains legacy tests for the loopclosure checker for GoVersion 0 { return tool.CommandLineErrorf("server does not take arguments, got %v", args) diff --git a/gopls/internal/golang/comment.go b/gopls/internal/golang/comment.go index ece123801ff..95f0df98293 100644 --- a/gopls/internal/golang/comment.go +++ b/gopls/internal/golang/comment.go @@ -1,19 +1,12 @@ -// Copyright 2019 The Go Authors. All rights reserved. +// Copyright 2022 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. -//go:build !go1.19 -// +build !go1.19 - package golang import ( - "bytes" - "io" - "regexp" - "strings" - "unicode" - "unicode/utf8" + "fmt" + "go/doc/comment" "golang.org/x/tools/gopls/internal/settings" ) @@ -23,364 +16,26 @@ import ( // so it is known not to have leading, trailing blank lines // nor to have trailing spaces at the end of lines. // The comment markers have already been removed. -// -// Each line is converted into a markdown line and empty lines are just converted to -// newlines. Heading are prefixed with `### ` to make it a markdown heading. -// -// A span of indented lines retains a 4 space prefix block, with the common indent -// prefix removed unless empty, in which case it will be converted to a newline. -// -// URLs in the comment text are converted into links. -func CommentToMarkdown(text string, _ *settings.Options) string { - buf := &bytes.Buffer{} - commentToMarkdown(buf, text) - return buf.String() -} - -var ( - mdNewline = []byte("\n") - mdHeader = []byte("### ") - mdIndent = []byte(" ") - mdLinkStart = []byte("[") - mdLinkDiv = []byte("](") - mdLinkEnd = []byte(")") -) - -func commentToMarkdown(w io.Writer, text string) { - blocks := blocks(text) - for i, b := range blocks { - switch b.op { - case opPara: - for _, line := range b.lines { - emphasize(w, line, true) - } - case opHead: - // The header block can consist of only one line. - // However, check the number of lines, just in case. - if len(b.lines) == 0 { - // Skip this block. - continue - } - header := b.lines[0] - - w.Write(mdHeader) - commentEscape(w, header, true) - // Header doesn't end with \n unlike the lines of other blocks. - w.Write(mdNewline) - case opPre: - for _, line := range b.lines { - if isBlank(line) { - w.Write(mdNewline) - continue - } - w.Write(mdIndent) - w.Write([]byte(line)) - } - } - - if i < len(blocks)-1 { - w.Write(mdNewline) - } - } -} - -const ( - ulquo = "“" - urquo = "”" -) - -var ( - markdownEscape = regexp.MustCompile(`([\\\x60*{}[\]()#+\-.!_>~|"$%&'\/:;<=?@^])`) - - unicodeQuoteReplacer = strings.NewReplacer("``", ulquo, "''", urquo) -) - -// commentEscape escapes comment text for markdown. If nice is set, -// also turn double ` and ' into “ and ”. -func commentEscape(w io.Writer, text string, nice bool) { - if nice { - text = convertQuotes(text) - } - text = escapeRegex(text) - w.Write([]byte(text)) -} - -func convertQuotes(text string) string { - return unicodeQuoteReplacer.Replace(text) -} - -func escapeRegex(text string) string { - return markdownEscape.ReplaceAllString(text, `\$1`) -} - -func emphasize(w io.Writer, line string, nice bool) { - for { - m := matchRx.FindStringSubmatchIndex(line) - if m == nil { - break - } - // m >= 6 (two parenthesized sub-regexps in matchRx, 1st one is urlRx) - - // write text before match - commentEscape(w, line[0:m[0]], nice) - - // adjust match for URLs - match := line[m[0]:m[1]] - if strings.Contains(match, "://") { - m0, m1 := m[0], m[1] - for _, s := range []string{"()", "{}", "[]"} { - open, close := s[:1], s[1:] // E.g., "(" and ")" - // require opening parentheses before closing parentheses (#22285) - if i := strings.Index(match, close); i >= 0 && i < strings.Index(match, open) { - m1 = m0 + i - match = line[m0:m1] - } - // require balanced pairs of parentheses (#5043) - for i := 0; strings.Count(match, open) != strings.Count(match, close) && i < 10; i++ { - m1 = strings.LastIndexAny(line[:m1], s) - match = line[m0:m1] - } - } - if m1 != m[1] { - // redo matching with shortened line for correct indices - m = matchRx.FindStringSubmatchIndex(line[:m[0]+len(match)]) - } - } - - // Following code has been modified from go/doc since words is always - // nil. All html formatting has also been transformed into markdown formatting - - // analyze match - url := "" - if m[2] >= 0 { - url = match - } - - // write match - if len(url) > 0 { - w.Write(mdLinkStart) - } - - commentEscape(w, match, nice) - - if len(url) > 0 { - w.Write(mdLinkDiv) - w.Write([]byte(urlReplacer.Replace(url))) - w.Write(mdLinkEnd) - } - - // advance - line = line[m[1]:] - } - commentEscape(w, line, nice) -} - -// Everything from here on is a copy of go/doc/comment.go - -const ( - // Regexp for Go identifiers - identRx = `[\pL_][\pL_0-9]*` - - // Regexp for URLs - // Match parens, and check later for balance - see #5043, #22285 - // Match .,:;?! within path, but not at end - see #18139, #16565 - // This excludes some rare yet valid urls ending in common punctuation - // in order to allow sentences ending in URLs. - - // protocol (required) e.g. http - protoPart = `(https?|ftp|file|gopher|mailto|nntp)` - // host (required) e.g. www.example.com or [::1]:8080 - hostPart = `([a-zA-Z0-9_@\-.\[\]:]+)` - // path+query+fragment (optional) e.g. /path/index.html?q=foo#bar - pathPart = `([.,:;?!]*[a-zA-Z0-9$'()*+&#=@~_/\-\[\]%])*` - - urlRx = protoPart + `://` + hostPart + pathPart -) - -var ( - matchRx = regexp.MustCompile(`(` + urlRx + `)|(` + identRx + `)`) - urlReplacer = strings.NewReplacer(`(`, `\(`, `)`, `\)`) -) - -func indentLen(s string) int { - i := 0 - for i < len(s) && (s[i] == ' ' || s[i] == '\t') { - i++ - } - return i -} - -func isBlank(s string) bool { - return len(s) == 0 || (len(s) == 1 && s[0] == '\n') -} - -func commonPrefix(a, b string) string { - i := 0 - for i < len(a) && i < len(b) && a[i] == b[i] { - i++ - } - return a[0:i] -} - -func unindent(block []string) { - if len(block) == 0 { - return - } - - // compute maximum common white prefix - prefix := block[0][0:indentLen(block[0])] - for _, line := range block { - if !isBlank(line) { - prefix = commonPrefix(prefix, line) - } - } - n := len(prefix) - - // remove - for i, line := range block { - if !isBlank(line) { - block[i] = line[n:] - } - } -} - -// heading returns the trimmed line if it passes as a section heading; -// otherwise it returns the empty string. -func heading(line string) string { - line = strings.TrimSpace(line) - if len(line) == 0 { - return "" - } - - // a heading must start with an uppercase letter - r, _ := utf8.DecodeRuneInString(line) - if !unicode.IsLetter(r) || !unicode.IsUpper(r) { - return "" - } - - // it must end in a letter or digit: - r, _ = utf8.DecodeLastRuneInString(line) - if !unicode.IsLetter(r) && !unicode.IsDigit(r) { - return "" - } - - // exclude lines with illegal characters. we allow "()," - if strings.ContainsAny(line, ";:!?+*/=[]{}_^°&§~%#@<\">\\") { - return "" - } - - // allow "'" for possessive "'s" only - for b := line; ; { - i := strings.IndexRune(b, '\'') - if i < 0 { - break - } - if i+1 >= len(b) || b[i+1] != 's' || (i+2 < len(b) && b[i+2] != ' ') { - return "" // not followed by "s " - } - b = b[i+2:] - } - - // allow "." when followed by non-space - for b := line; ; { - i := strings.IndexRune(b, '.') - if i < 0 { - break - } - if i+1 >= len(b) || b[i+1] == ' ' { - return "" // not followed by non-space - } - b = b[i+1:] - } - - return line -} - -type op int - -const ( - opPara op = iota - opHead - opPre -) - -type block struct { - op op - lines []string -} - -func blocks(text string) []block { - var ( - out []block - para []string - - lastWasBlank = false - lastWasHeading = false - ) - - close := func() { - if para != nil { - out = append(out, block{opPara, para}) - para = nil - } - } - - lines := strings.SplitAfter(text, "\n") - unindent(lines) - for i := 0; i < len(lines); { - line := lines[i] - if isBlank(line) { - // close paragraph - close() - i++ - lastWasBlank = true - continue - } - if indentLen(line) > 0 { - // close paragraph - close() - - // count indented or blank lines - j := i + 1 - for j < len(lines) && (isBlank(lines[j]) || indentLen(lines[j]) > 0) { - j++ - } - // but not trailing blank lines - for j > i && isBlank(lines[j-1]) { - j-- - } - pre := lines[i:j] - i = j - - unindent(pre) - - // put those lines in a pre block - out = append(out, block{opPre, pre}) - lastWasHeading = false - continue - } - - if lastWasBlank && !lastWasHeading && i+2 < len(lines) && - isBlank(lines[i+1]) && !isBlank(lines[i+2]) && indentLen(lines[i+2]) == 0 { - // current line is non-blank, surrounded by blank lines - // and the next non-blank line is not indented: this - // might be a heading. - if head := heading(line); head != "" { - close() - out = append(out, block{opHead, []string{head}}) - i += 2 - lastWasHeading = true - continue - } - } - - // open paragraph - lastWasBlank = false - lastWasHeading = false - para = append(para, lines[i]) - i++ - } - close() - - return out +func CommentToMarkdown(text string, options *settings.Options) string { + var p comment.Parser + doc := p.Parse(text) + var pr comment.Printer + // The default produces {#Hdr-...} tags for headings. + // vscode displays thems, which is undesirable. + // The godoc for comment.Printer says the tags + // avoid a security problem. + pr.HeadingID = func(*comment.Heading) string { return "" } + pr.DocLinkURL = func(link *comment.DocLink) string { + msg := fmt.Sprintf("https://%s/%s", options.LinkTarget, link.ImportPath) + if link.Name != "" { + msg += "#" + if link.Recv != "" { + msg += link.Recv + "." + } + msg += link.Name + } + return msg + } + easy := pr.Markdown(doc) + return string(easy) } diff --git a/gopls/internal/golang/comment_go118_test.go b/gopls/internal/golang/comment_go118_test.go deleted file mode 100644 index c38898a28e6..00000000000 --- a/gopls/internal/golang/comment_go118_test.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2019 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. - -//go:build !go1.19 -// +build !go1.19 - -package golang - -import ( - "bytes" - "reflect" - "strings" - "testing" -) - -// This file is a copy of go/doc/comment_test.go with the exception for -// the test cases for TestEmphasize and TestCommentEscape - -var headingTests = []struct { - line string - ok bool -}{ - {"Section", true}, - {"A typical usage", true}, - {"ΔΛΞ is Greek", true}, - {"Foo 42", true}, - {"", false}, - {"section", false}, - {"A typical usage:", false}, - {"This code:", false}, - {"δ is Greek", false}, - {"Foo §", false}, - {"Fermat's Last Sentence", true}, - {"Fermat's", true}, - {"'sX", false}, - {"Ted 'Too' Bar", false}, - {"Use n+m", false}, - {"Scanning:", false}, - {"N:M", false}, -} - -func TestIsHeading(t *testing.T) { - for _, tt := range headingTests { - if h := heading(tt.line); (len(h) > 0) != tt.ok { - t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok) - } - } -} - -var blocksTests = []struct { - in string - out []block - text string -}{ - { - in: `Para 1. -Para 1 line 2. - -Para 2. - -Section - -Para 3. - - pre - pre1 - -Para 4. - - pre - pre1 - - pre2 - -Para 5. - - - pre - - - pre1 - pre2 - -Para 6. - pre - pre2 -`, - out: []block{ - {opPara, []string{"Para 1.\n", "Para 1 line 2.\n"}}, - {opPara, []string{"Para 2.\n"}}, - {opHead, []string{"Section"}}, - {opPara, []string{"Para 3.\n"}}, - {opPre, []string{"pre\n", "pre1\n"}}, - {opPara, []string{"Para 4.\n"}}, - {opPre, []string{"pre\n", "pre1\n", "\n", "pre2\n"}}, - {opPara, []string{"Para 5.\n"}}, - {opPre, []string{"pre\n", "\n", "\n", "pre1\n", "pre2\n"}}, - {opPara, []string{"Para 6.\n"}}, - {opPre, []string{"pre\n", "pre2\n"}}, - }, - text: `. Para 1. Para 1 line 2. - -. Para 2. - - -. Section - -. Para 3. - -$ pre -$ pre1 - -. Para 4. - -$ pre -$ pre1 - -$ pre2 - -. Para 5. - -$ pre - - -$ pre1 -$ pre2 - -. Para 6. - -$ pre -$ pre2 -`, - }, - { - in: "Para.\n\tshould not be ``escaped''", - out: []block{ - {opPara, []string{"Para.\n"}}, - {opPre, []string{"should not be ``escaped''"}}, - }, - text: ". Para.\n\n$ should not be ``escaped''", - }, - { - in: "// A very long line of 46 char for line wrapping.", - out: []block{ - {opPara, []string{"// A very long line of 46 char for line wrapping."}}, - }, - text: `. // A very long line of 46 char for line -. // wrapping. -`, - }, - { - in: `/* A very long line of 46 char for line wrapping. -A very long line of 46 char for line wrapping. */`, - out: []block{ - {opPara, []string{"/* A very long line of 46 char for line wrapping.\n", "A very long line of 46 char for line wrapping. */"}}, - }, - text: `. /* A very long line of 46 char for line -. wrapping. A very long line of 46 char -. for line wrapping. */ -`, - }, -} - -func TestBlocks(t *testing.T) { - for i, tt := range blocksTests { - b := blocks(tt.in) - if !reflect.DeepEqual(b, tt.out) { - t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, b, tt.out) - } - } -} - -// This has been modified from go/doc to use markdown links instead of html ones -// and use markdown escaping instead oh html -var emphasizeTests = []struct { - in, out string -}{ - {"", ""}, - {"http://[::1]:8080/foo.txt", `[http\:\/\/\[\:\:1\]\:8080\/foo\.txt](http://[::1]:8080/foo.txt)`}, - {"before (https://www.google.com) after", `before \([https\:\/\/www\.google\.com](https://www.google.com)\) after`}, - {"before https://www.google.com:30/x/y/z:b::c. After", `before [https\:\/\/www\.google\.com\:30\/x\/y\/z\:b\:\:c](https://www.google.com:30/x/y/z:b::c)\. After`}, - {"http://www.google.com/path/:;!-/?query=%34b#093124", `[http\:\/\/www\.google\.com\/path\/\:\;\!\-\/\?query\=\%34b\#093124](http://www.google.com/path/:;!-/?query=%34b#093124)`}, - {"http://www.google.com/path/:;!-/?query=%34bar#093124", `[http\:\/\/www\.google\.com\/path\/\:\;\!\-\/\?query\=\%34bar\#093124](http://www.google.com/path/:;!-/?query=%34bar#093124)`}, - {"http://www.google.com/index.html! After", `[http\:\/\/www\.google\.com\/index\.html](http://www.google.com/index.html)\! After`}, - {"http://www.google.com/", `[http\:\/\/www\.google\.com\/](http://www.google.com/)`}, - {"https://www.google.com/", `[https\:\/\/www\.google\.com\/](https://www.google.com/)`}, - {"http://www.google.com/path.", `[http\:\/\/www\.google\.com\/path](http://www.google.com/path)\.`}, - {"http://en.wikipedia.org/wiki/Camellia_(cipher)", `[http\:\/\/en\.wikipedia\.org\/wiki\/Camellia\_\(cipher\)](http://en.wikipedia.org/wiki/Camellia_\(cipher\))`}, - {"(http://www.google.com/)", `\([http\:\/\/www\.google\.com\/](http://www.google.com/)\)`}, - {"http://gmail.com)", `[http\:\/\/gmail\.com](http://gmail.com)\)`}, - {"((http://gmail.com))", `\(\([http\:\/\/gmail\.com](http://gmail.com)\)\)`}, - {"http://gmail.com ((http://gmail.com)) ()", `[http\:\/\/gmail\.com](http://gmail.com) \(\([http\:\/\/gmail\.com](http://gmail.com)\)\) \(\)`}, - {"Foo bar http://example.com/ quux!", `Foo bar [http\:\/\/example\.com\/](http://example.com/) quux\!`}, - {"Hello http://example.com/%2f/ /world.", `Hello [http\:\/\/example\.com\/\%2f\/](http://example.com/%2f/) \/world\.`}, - {"Lorem http: ipsum //host/path", `Lorem http\: ipsum \/\/host\/path`}, - {"javascript://is/not/linked", `javascript\:\/\/is\/not\/linked`}, - {"http://foo", `[http\:\/\/foo](http://foo)`}, - {"art by [[https://www.example.com/person/][Person Name]]", `art by \[\[[https\:\/\/www\.example\.com\/person\/](https://www.example.com/person/)\]\[Person Name\]\]`}, - {"please visit (http://golang.org/)", `please visit \([http\:\/\/golang\.org\/](http://golang.org/)\)`}, - {"please visit http://golang.org/hello())", `please visit [http\:\/\/golang\.org\/hello\(\)](http://golang.org/hello\(\))\)`}, - {"http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD", `[http\:\/\/git\.qemu\.org\/\?p\=qemu\.git\;a\=blob\;f\=qapi\-schema\.json\;hb\=HEAD](http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD)`}, - {"https://foo.bar/bal/x(])", `[https\:\/\/foo\.bar\/bal\/x\(](https://foo.bar/bal/x\()\]\)`}, - {"foo [ http://bar(])", `foo \[ [http\:\/\/bar\(](http://bar\()\]\)`}, -} - -func TestEmphasize(t *testing.T) { - for i, tt := range emphasizeTests { - var buf bytes.Buffer - emphasize(&buf, tt.in, true) - out := buf.String() - if out != tt.out { - t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, out, tt.out) - } - } -} - -func TestCommentEscape(t *testing.T) { - //ldquo -> ulquo and rdquo -> urquo - commentTests := []struct { - in, out string - }{ - {"typically invoked as ``go tool asm'',", "typically invoked as " + ulquo + "go tool asm" + urquo + ","}, - {"For more detail, run ``go help test'' and ``go help testflag''", "For more detail, run " + ulquo + "go help test" + urquo + " and " + ulquo + "go help testflag" + urquo}} - for i, tt := range commentTests { - var buf strings.Builder - commentEscape(&buf, tt.in, true) - out := buf.String() - if out != tt.out { - t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, out, tt.out) - } - } -} - -func TestCommentToMarkdown(t *testing.T) { - tests := []struct { - in, out string - }{ - { - in: "F declaration.\n", - out: "F declaration\\.\n", - }, - { - in: ` -F declaration. Lorem ipsum dolor sit amet. -Etiam mattis eros at orci mollis molestie. -`, - out: ` -F declaration\. Lorem ipsum dolor sit amet\. -Etiam mattis eros at orci mollis molestie\. -`, - }, - { - in: ` -F declaration. - -Lorem ipsum dolor sit amet. -Sed id dui turpis. - - - - -Aenean tempus velit non auctor eleifend. -Aenean efficitur a sem id ultricies. - - -Phasellus efficitur mauris et viverra bibendum. -`, - out: ` -F declaration\. - -Lorem ipsum dolor sit amet\. -Sed id dui turpis\. - -Aenean tempus velit non auctor eleifend\. -Aenean efficitur a sem id ultricies\. - -Phasellus efficitur mauris et viverra bibendum\. -`, - }, - { - in: ` -F declaration. - -Aenean tempus velit non auctor eleifend. - -Section - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. - - func foo() {} - - - func bar() {} - -Fusce lorem lacus. - - func foo() {} - - func bar() {} - -Maecenas in lobortis lectus. - - func foo() {} - - func bar() {} - -Phasellus efficitur mauris et viverra bibendum. -`, - out: ` -F declaration\. - -Aenean tempus velit non auctor eleifend\. - -### Section - -Lorem ipsum dolor sit amet, consectetur adipiscing elit\. - - func foo() {} - - - func bar() {} - -Fusce lorem lacus\. - - func foo() {} - - func bar() {} - -Maecenas in lobortis lectus\. - - func foo() {} - - func bar() {} - -Phasellus efficitur mauris et viverra bibendum\. -`, - }, - { - in: ` -F declaration. - - func foo() { - fmt.Println("foo") - } - func bar() { - fmt.Println("bar") - } -`, - out: ` -F declaration\. - - func foo() { - fmt.Println("foo") - } - func bar() { - fmt.Println("bar") - } -`, - }, - } - for i, tt := range tests { - // Comments start with new lines for better readability. So, we should trim them. - tt.in = strings.TrimPrefix(tt.in, "\n") - tt.out = strings.TrimPrefix(tt.out, "\n") - - if out := CommentToMarkdown(tt.in, nil); out != tt.out { - t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, out, tt.out) - } - } -} diff --git a/gopls/internal/golang/comment_go119.go b/gopls/internal/golang/comment_go119.go deleted file mode 100644 index eec338d54fa..00000000000 --- a/gopls/internal/golang/comment_go119.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2022 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. - -//go:build go1.19 -// +build go1.19 - -package golang - -// Starting with go1.19, the formatting of comments has changed, and there -// is a new package (go/doc/comment) for processing them. -// As long as gopls has to compile under earlier versions, tests -// have to pass with both the old and new code, which produce -// slightly different results. - -// When gopls no longer needs to compile with go1.18, the old comment.go should -// be replaced by this file, the golden test files should be updated. -// (and checkSameMarkdown() could be replaced by a simple comparison.) - -import ( - "fmt" - "go/doc/comment" - - "golang.org/x/tools/gopls/internal/settings" -) - -// CommentToMarkdown converts comment text to formatted markdown. -// The comment was prepared by DocReader, -// so it is known not to have leading, trailing blank lines -// nor to have trailing spaces at the end of lines. -// The comment markers have already been removed. -func CommentToMarkdown(text string, options *settings.Options) string { - var p comment.Parser - doc := p.Parse(text) - var pr comment.Printer - // The default produces {#Hdr-...} tags for headings. - // vscode displays thems, which is undesirable. - // The godoc for comment.Printer says the tags - // avoid a security problem. - pr.HeadingID = func(*comment.Heading) string { return "" } - pr.DocLinkURL = func(link *comment.DocLink) string { - msg := fmt.Sprintf("https://%s/%s", options.LinkTarget, link.ImportPath) - if link.Name != "" { - msg += "#" - if link.Recv != "" { - msg += link.Recv + "." - } - msg += link.Name - } - return msg - } - easy := pr.Markdown(doc) - return string(easy) -} diff --git a/gopls/internal/golang/origin.go b/gopls/internal/golang/origin.go index c5e84db0ceb..aa77a9b3aa4 100644 --- a/gopls/internal/golang/origin.go +++ b/gopls/internal/golang/origin.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !go1.19 -// +build !go1.19 - package golang import "go/types" @@ -13,14 +10,21 @@ import "go/types" // with the same origin as the provided obj (which may be a synthetic object // created during instantiation). func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { - if obj == nil { - return objSet[obj] - } - // In Go 1.18, we can't use the types.Var.Origin and types.Func.Origin methods. + objOrigin := origin(obj) for target := range objSet { - if target.Pkg() == obj.Pkg() && target.Pos() == obj.Pos() && target.Name() == obj.Name() { + if origin(target) == objOrigin { return true } } return false } + +func origin(obj types.Object) types.Object { + switch obj := obj.(type) { + case *types.Var: + return obj.Origin() + case *types.Func: + return obj.Origin() + } + return obj +} diff --git a/gopls/internal/golang/origin_119.go b/gopls/internal/golang/origin_119.go deleted file mode 100644 index 16f6ca7c065..00000000000 --- a/gopls/internal/golang/origin_119.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 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. - -//go:build go1.19 -// +build go1.19 - -package golang - -import "go/types" - -// containsOrigin reports whether the provided object set contains an object -// with the same origin as the provided obj (which may be a synthetic object -// created during instantiation). -func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { - objOrigin := origin(obj) - for target := range objSet { - if origin(target) == objOrigin { - return true - } - } - return false -} - -func origin(obj types.Object) types.Object { - switch obj := obj.(type) { - case *types.Var: - return obj.Origin() - case *types.Func: - return obj.Origin() - } - return obj -} diff --git a/gopls/internal/golang/rename.go b/gopls/internal/golang/rename.go index 81114fc6a09..8c40079b2f3 100644 --- a/gopls/internal/golang/rename.go +++ b/gopls/internal/golang/rename.go @@ -68,7 +68,6 @@ import ( "golang.org/x/tools/gopls/internal/util/safetoken" "golang.org/x/tools/internal/diff" "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typesinternal" "golang.org/x/tools/refactor/satisfy" ) @@ -347,8 +346,7 @@ func renameOrdinary(ctx context.Context, snapshot *cache.Snapshot, f file.Handle var declObjPath objectpath.Path if obj.Exported() { // objectpath.For requires the origin of a generic function or type, not an - // instantiation (a bug?). Unfortunately we can't call Func.Origin as this - // is not available in go/types@go1.18. So we take a scenic route. + // instantiation (a bug?). // // Note that unlike Funcs, TypeNames are always canonical (they are "left" // of the type parameters, unlike methods). @@ -360,7 +358,7 @@ func renameOrdinary(ctx context.Context, snapshot *cache.Snapshot, f file.Handle goto skipObjectPath } case *types.Func: - obj = funcOrigin(obj.(*types.Func)) + obj = obj.(*types.Func).Origin() case *types.Var: // TODO(adonovan): do vars need the origin treatment too? (issue #58462) @@ -451,23 +449,6 @@ func renameOrdinary(ctx context.Context, snapshot *cache.Snapshot, f file.Handle return renameExported(pkgs, declPkgPath, declObjPath, newName) } -// funcOrigin is a go1.18-portable implementation of (*types.Func).Origin. -func funcOrigin(fn *types.Func) *types.Func { - // Method? - if fn.Type().(*types.Signature).Recv() != nil { - return typeparams.OriginMethod(fn) - } - - // Package-level function? - // (Assume the origin has the same position.) - gen := fn.Pkg().Scope().Lookup(fn.Name()) - if gen != nil && gen.Pos() == fn.Pos() { - return gen.(*types.Func) - } - - return fn -} - // typeCheckReverseDependencies returns the type-checked packages for // the reverse dependencies of all packages variants containing // file declURI. The packages are in some topological order. diff --git a/gopls/internal/protocol/generate/generate.go b/gopls/internal/protocol/generate/generate.go index 0496b7d060c..7418918f51f 100644 --- a/gopls/internal/protocol/generate/generate.go +++ b/gopls/internal/protocol/generate/generate.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import ( diff --git a/gopls/internal/protocol/generate/main.go b/gopls/internal/protocol/generate/main.go index f70c5810d6c..bdc2728e2a9 100644 --- a/gopls/internal/protocol/generate/main.go +++ b/gopls/internal/protocol/generate/main.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - // The generate command generates Go declarations from VSCode's // description of the Language Server Protocol. // diff --git a/gopls/internal/protocol/generate/main_test.go b/gopls/internal/protocol/generate/main_test.go index 5f336690687..73c22048a80 100644 --- a/gopls/internal/protocol/generate/main_test.go +++ b/gopls/internal/protocol/generate/main_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import ( diff --git a/gopls/internal/protocol/generate/output.go b/gopls/internal/protocol/generate/output.go index fc64677ff8e..47608626b82 100644 --- a/gopls/internal/protocol/generate/output.go +++ b/gopls/internal/protocol/generate/output.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import ( diff --git a/gopls/internal/protocol/generate/tables.go b/gopls/internal/protocol/generate/tables.go index ac428b58479..a9207bfc9a3 100644 --- a/gopls/internal/protocol/generate/tables.go +++ b/gopls/internal/protocol/generate/tables.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import "log" diff --git a/gopls/internal/protocol/generate/typenames.go b/gopls/internal/protocol/generate/typenames.go index 8bacdd2a1cf..83f25a010a0 100644 --- a/gopls/internal/protocol/generate/typenames.go +++ b/gopls/internal/protocol/generate/typenames.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import ( diff --git a/gopls/internal/protocol/generate/types.go b/gopls/internal/protocol/generate/types.go index 0d01ae43cb1..0537748eb5b 100644 --- a/gopls/internal/protocol/generate/types.go +++ b/gopls/internal/protocol/generate/types.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.19 -// +build go1.19 - package main import ( diff --git a/gopls/internal/protocol/protocol.go b/gopls/internal/protocol/protocol.go index 09bfaca2e86..7cc5589aa0b 100644 --- a/gopls/internal/protocol/protocol.go +++ b/gopls/internal/protocol/protocol.go @@ -11,7 +11,7 @@ import ( "fmt" "io" - "golang.org/x/tools/gopls/internal/telemetry" + "golang.org/x/telemetry/crashmonitor" "golang.org/x/tools/gopls/internal/util/bug" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/jsonrpc2" @@ -302,7 +302,7 @@ func recoverHandlerPanic(method string) { // Report panics in the handler goroutine, // unless we have enabled the monitor, // which reports all crashes. - if !telemetry.CrashMonitorSupported() { + if !crashmonitor.Supported() { defer func() { if x := recover(); x != nil { bug.Reportf("panic in %s request", method) diff --git a/gopls/internal/server/command.go b/gopls/internal/server/command.go index 19ea884f45d..3f5d53c53a2 100644 --- a/gopls/internal/server/command.go +++ b/gopls/internal/server/command.go @@ -21,6 +21,7 @@ import ( "sync" "golang.org/x/mod/modfile" + "golang.org/x/telemetry/counter" "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/gopls/internal/cache" "golang.org/x/tools/gopls/internal/cache/metadata" @@ -32,7 +33,6 @@ import ( "golang.org/x/tools/gopls/internal/protocol" "golang.org/x/tools/gopls/internal/protocol/command" "golang.org/x/tools/gopls/internal/settings" - "golang.org/x/tools/gopls/internal/telemetry" "golang.org/x/tools/gopls/internal/util/bug" "golang.org/x/tools/gopls/internal/vulncheck" "golang.org/x/tools/gopls/internal/vulncheck/scan" @@ -80,7 +80,13 @@ func (*commandHandler) AddTelemetryCounters(_ context.Context, args command.AddT return fmt.Errorf("Names and Values must have the same length") } // invalid counter update requests will be silently dropped. (no audience) - telemetry.AddForwardedCounters(args.Names, args.Values) + for i, n := range args.Names { + v := args.Values[i] + if n == "" || v < 0 { + continue + } + counter.Add("fwd/"+n, v) + } return nil } diff --git a/gopls/internal/server/general.go b/gopls/internal/server/general.go index cdaee1b973b..9ead4705cea 100644 --- a/gopls/internal/server/general.go +++ b/gopls/internal/server/general.go @@ -20,12 +20,12 @@ import ( "strings" "sync" + "golang.org/x/telemetry/counter" "golang.org/x/tools/gopls/internal/cache" "golang.org/x/tools/gopls/internal/debug" "golang.org/x/tools/gopls/internal/file" "golang.org/x/tools/gopls/internal/protocol" "golang.org/x/tools/gopls/internal/settings" - "golang.org/x/tools/gopls/internal/telemetry" "golang.org/x/tools/gopls/internal/util/bug" "golang.org/x/tools/gopls/internal/util/goversion" "golang.org/x/tools/gopls/internal/util/maps" @@ -41,7 +41,7 @@ func (s *server) Initialize(ctx context.Context, params *protocol.ParamInitializ if params != nil && params.ClientInfo != nil { clientName = params.ClientInfo.Name } - telemetry.RecordClientInfo(clientName) + recordClientInfo(clientName) s.stateMu.Lock() if s.state >= serverInitializing { @@ -249,7 +249,9 @@ func (s *server) checkViewGoVersions() { if oldestVersion == -1 || viewVersion < oldestVersion { oldestVersion, fromBuild = viewVersion, false } - telemetry.RecordViewGoVersion(viewVersion) + if viewVersion >= 0 { + counter.Inc(fmt.Sprintf("gopls/goversion:1.%d", viewVersion)) + } } if msg, isError := goversion.Message(oldestVersion, fromBuild); msg != "" { @@ -637,3 +639,42 @@ func (s *server) Exit(ctx context.Context) error { // close naturally if needed after the connection is closed. return nil } + +// recordClientInfo records gopls client info. +func recordClientInfo(clientName string) { + key := "gopls/client:other" + switch clientName { + case "Visual Studio Code": + key = "gopls/client:vscode" + case "Visual Studio Code - Insiders": + key = "gopls/client:vscode-insiders" + case "VSCodium": + key = "gopls/client:vscodium" + case "code-server": + // https://github.com/coder/code-server/blob/3cb92edc76ecc2cfa5809205897d93d4379b16a6/ci/build/build-vscode.sh#L19 + key = "gopls/client:code-server" + case "Eglot": + // https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-03/msg00954.html + key = "gopls/client:eglot" + case "govim": + // https://github.com/govim/govim/pull/1189 + key = "gopls/client:govim" + case "Neovim": + // https://github.com/neovim/neovim/blob/42333ea98dfcd2994ee128a3467dfe68205154cd/runtime/lua/vim/lsp.lua#L1361 + key = "gopls/client:neovim" + case "coc.nvim": + // https://github.com/neoclide/coc.nvim/blob/3dc6153a85ed0f185abec1deb972a66af3fbbfb4/src/language-client/client.ts#L994 + key = "gopls/client:coc.nvim" + case "Sublime Text LSP": + // https://github.com/sublimelsp/LSP/blob/e608f878e7e9dd34aabe4ff0462540fadcd88fcc/plugin/core/sessions.py#L493 + key = "gopls/client:sublimetext" + default: + // Accumulate at least a local counter for an unknown + // client name, but also fall through to count it as + // ":other" for collection. + if clientName != "" { + counter.New(fmt.Sprintf("gopls/client-other:%s", clientName)).Inc() + } + } + counter.Inc(key) +} diff --git a/gopls/internal/server/prompt.go b/gopls/internal/server/prompt.go index 72c5113dc4e..7dc16b9a324 100644 --- a/gopls/internal/server/prompt.go +++ b/gopls/internal/server/prompt.go @@ -11,8 +11,8 @@ import ( "path/filepath" "time" + "golang.org/x/telemetry" "golang.org/x/tools/gopls/internal/protocol" - "golang.org/x/tools/gopls/internal/telemetry" "golang.org/x/tools/internal/event" ) diff --git a/gopls/internal/telemetry/telemetry.go b/gopls/internal/telemetry/telemetry.go deleted file mode 100644 index 58083992a17..00000000000 --- a/gopls/internal/telemetry/telemetry.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2023 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. - -//go:build go1.19 -// +build go1.19 - -package telemetry - -import ( - "fmt" - - "golang.org/x/telemetry" - "golang.org/x/telemetry/counter" - "golang.org/x/telemetry/crashmonitor" - "golang.org/x/telemetry/upload" -) - -// Start starts telemetry, including the crash monitor. -func Start() { - telemetry.Start(telemetry.Config{ReportCrashes: true}) -} - -// CrashMonitorSupported calls [crashmonitor.Supported]. -func CrashMonitorSupported() bool { - return crashmonitor.Supported() -} - -// NewStackCounter calls [counter.NewStack]. -func NewStackCounter(name string, depth int) *counter.StackCounter { - return counter.NewStack(name, depth) -} - -// Mode calls x/telemetry.Mode. -func Mode() string { - return telemetry.Mode() -} - -// SetMode calls x/telemetry.SetMode. -func SetMode(mode string) error { - return telemetry.SetMode(mode) -} - -// Upload starts a goroutine for telemetry upload. -func Upload() { - go upload.Run(nil) -} - -// RecordClientInfo records gopls client info. -func RecordClientInfo(clientName string) { - key := "gopls/client:other" - switch clientName { - case "Visual Studio Code": - key = "gopls/client:vscode" - case "Visual Studio Code - Insiders": - key = "gopls/client:vscode-insiders" - case "VSCodium": - key = "gopls/client:vscodium" - case "code-server": - // https://github.com/coder/code-server/blob/3cb92edc76ecc2cfa5809205897d93d4379b16a6/ci/build/build-vscode.sh#L19 - key = "gopls/client:code-server" - case "Eglot": - // https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-03/msg00954.html - key = "gopls/client:eglot" - case "govim": - // https://github.com/govim/govim/pull/1189 - key = "gopls/client:govim" - case "Neovim": - // https://github.com/neovim/neovim/blob/42333ea98dfcd2994ee128a3467dfe68205154cd/runtime/lua/vim/lsp.lua#L1361 - key = "gopls/client:neovim" - case "coc.nvim": - // https://github.com/neoclide/coc.nvim/blob/3dc6153a85ed0f185abec1deb972a66af3fbbfb4/src/language-client/client.ts#L994 - key = "gopls/client:coc.nvim" - case "Sublime Text LSP": - // https://github.com/sublimelsp/LSP/blob/e608f878e7e9dd34aabe4ff0462540fadcd88fcc/plugin/core/sessions.py#L493 - key = "gopls/client:sublimetext" - default: - // Accumulate at least a local counter for an unknown - // client name, but also fall through to count it as - // ":other" for collection. - if clientName != "" { - counter.New(fmt.Sprintf("gopls/client-other:%s", clientName)).Inc() - } - } - counter.Inc(key) -} - -// RecordViewGoVersion records the Go minor version number (1.x) used for a view. -func RecordViewGoVersion(x int) { - if x < 0 { - return - } - name := fmt.Sprintf("gopls/goversion:1.%d", x) - counter.Inc(name) -} - -// AddForwardedCounters adds the given counters on behalf of clients. -// Names and values must have the same length. -func AddForwardedCounters(names []string, values []int64) { - for i, n := range names { - v := values[i] - if n == "" || v < 0 { - continue // Should we report an error? Who is the audience? - } - counter.Add("fwd/"+n, v) - } -} diff --git a/gopls/internal/telemetry/telemetry_go118.go b/gopls/internal/telemetry/telemetry_go118.go deleted file mode 100644 index 3fd1df2939c..00000000000 --- a/gopls/internal/telemetry/telemetry_go118.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2023 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. - -//go:build !go1.19 -// +build !go1.19 - -package telemetry - -// This file defines dummy implementations of telemetry operations to -// permit building with go1.18. Until we drop support for go1.18, -// gopls may not refer to the telemetry module directly, but must go -// through this file. - -func Start() {} - -func CrashMonitorSupported() bool { return false } - -func NewStackCounter(string, int) dummyCounter { return dummyCounter{} } - -type dummyCounter struct{} - -func (dummyCounter) Inc() {} - -func Mode() string { - return "local" -} - -func SetMode(mode string) error { - return nil -} - -func Upload() { -} - -func RecordClientInfo(string) {} - -func RecordViewGoVersion(x int) { -} - -func AddForwardedCounters(names []string, values []int64) { -} diff --git a/gopls/internal/test/integration/completion/completion18_test.go b/gopls/internal/test/integration/completion/completion18_test.go index 0ca83778664..a35061d693b 100644 --- a/gopls/internal/test/integration/completion/completion18_test.go +++ b/gopls/internal/test/integration/completion/completion18_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package completion import ( diff --git a/gopls/internal/test/integration/misc/configuration_test.go b/gopls/internal/test/integration/misc/configuration_test.go index c6ed18041ae..39980f353df 100644 --- a/gopls/internal/test/integration/misc/configuration_test.go +++ b/gopls/internal/test/integration/misc/configuration_test.go @@ -15,7 +15,7 @@ import ( // Test that enabling and disabling produces the expected results of showing // and hiding staticcheck analysis results. func TestChangeConfiguration(t *testing.T) { - // Staticcheck only supports Go versions >= 1.19. + // Staticcheck only supports Go versions >= 1.20. // Note: keep this in sync with TestStaticcheckWarning. Below this version we // should get an error when setting staticcheck configuration. testenv.NeedsGo1Point(t, 20) @@ -164,19 +164,6 @@ var FooErr = errors.New("foo") }) } -func TestGofumptWarning(t *testing.T) { - testenv.SkipAfterGo1Point(t, 17) - - WithOptions( - Settings{"gofumpt": true}, - ).Run(t, "", func(t *testing.T, env *Env) { - env.OnceMet( - InitialWorkspaceLoad, - ShownMessage("gofumpt is not supported"), - ) - }) -} - func TestDeprecatedSettings(t *testing.T) { WithOptions( Settings{ diff --git a/gopls/internal/test/integration/misc/vuln_test.go b/gopls/internal/test/integration/misc/vuln_test.go index f74c1c38d77..b2bd520759b 100644 --- a/gopls/internal/test/integration/misc/vuln_test.go +++ b/gopls/internal/test/integration/misc/vuln_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package misc import ( @@ -167,7 +164,7 @@ func TestRunGovulncheckStd(t *testing.T) { -- go.mod -- module mod.com -go 1.18 +go 1.19 -- main.go -- package main @@ -192,9 +189,9 @@ func main() { // Let the analyzer read vulnerabilities data from the testdata/vulndb. "GOVULNDB": db.URI(), // When fetchinging stdlib package vulnerability info, - // behave as if our go version is go1.18 for this testing. + // behave as if our go version is go1.19 for this testing. // The default behavior is to run `go env GOVERSION` (which isn't mutable env var). - cache.GoVersionForVulnTest: "go1.18", + cache.GoVersionForVulnTest: "go1.19", "_GOPLS_TEST_BINARY_RUN_AS_GOPLS": "true", // needed to run `gopls vulncheck`. }, Settings{ diff --git a/gopls/internal/test/marker/marker_test.go b/gopls/internal/test/marker/marker_test.go index 1652eec7282..c32b81ac6bc 100644 --- a/gopls/internal/test/marker/marker_test.go +++ b/gopls/internal/test/marker/marker_test.go @@ -230,19 +230,14 @@ func Test(t *testing.T) { if err := os.WriteFile(filename, formatted, 0644); err != nil { t.Error(err) } - } else { - // On go 1.19 and later, verify that the testdata has not changed. - // - // On earlier Go versions, the golden test data varies due to different - // markdown escaping. + } else if !t.Failed() { + // Verify that the testdata has not changed. // // Only check this if the test hasn't already failed, otherwise we'd // report duplicate mismatches of golden data. - if testenv.Go1Point() >= 19 && !t.Failed() { - // Otherwise, verify that formatted content matches. - if diff := compare.NamedText("formatted", "on-disk", string(formatted), string(test.content)); diff != "" { - t.Errorf("formatted test does not match on-disk content:\n%s", diff) - } + // Otherwise, verify that formatted content matches. + if diff := compare.NamedText("formatted", "on-disk", string(formatted), string(test.content)); diff != "" { + t.Errorf("formatted test does not match on-disk content:\n%s", diff) } } }) diff --git a/gopls/internal/test/marker/testdata/definition/embed.txt b/gopls/internal/test/marker/testdata/definition/embed.txt index 9842c37d047..bd503869f8b 100644 --- a/gopls/internal/test/marker/testdata/definition/embed.txt +++ b/gopls/internal/test/marker/testdata/definition/embed.txt @@ -1,10 +1,5 @@ This test checks definition and hover operations over embedded fields and methods. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/definition/import.txt b/gopls/internal/test/marker/testdata/definition/import.txt index c0e5d76c00f..2ae95a8c29b 100644 --- a/gopls/internal/test/marker/testdata/definition/import.txt +++ b/gopls/internal/test/marker/testdata/definition/import.txt @@ -1,10 +1,5 @@ This test checks definition and hover over imports. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/definition/misc.txt b/gopls/internal/test/marker/testdata/definition/misc.txt index c7147a625be..82c15b5d2ba 100644 --- a/gopls/internal/test/marker/testdata/definition/misc.txt +++ b/gopls/internal/test/marker/testdata/definition/misc.txt @@ -1,10 +1,5 @@ This test exercises miscellaneous definition and hover requests. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/diagnostics/issue60544.txt b/gopls/internal/test/marker/testdata/diagnostics/issue60544.txt index b644d453164..6b8d6ce0ad2 100644 --- a/gopls/internal/test/marker/testdata/diagnostics/issue60544.txt +++ b/gopls/internal/test/marker/testdata/diagnostics/issue60544.txt @@ -1,10 +1,6 @@ This test exercises a crash due to treatment of "comparable" in methodset calculation (golang/go#60544). --min_go is 1.19 as the error message changed at this Go version. --- flags -- --min_go=go1.19 - -- main.go -- package main diff --git a/gopls/internal/test/marker/testdata/diagnostics/rundespiteerrors.txt b/gopls/internal/test/marker/testdata/diagnostics/rundespiteerrors.txt index a60cdeebeeb..b14f4dfabd0 100644 --- a/gopls/internal/test/marker/testdata/diagnostics/rundespiteerrors.txt +++ b/gopls/internal/test/marker/testdata/diagnostics/rundespiteerrors.txt @@ -1,9 +1,6 @@ This test verifies that analyzers without RunDespiteErrors are not executed on a package containing type errors (see issue #54762). -We require go1.18 because the range of the `1 + ""` go/types error -changed then, and the new @diag marker is quite particular. - -- go.mod -- module example.com go 1.12 diff --git a/gopls/internal/test/marker/testdata/hover/basiclit.txt b/gopls/internal/test/marker/testdata/hover/basiclit.txt index 9269c289840..9c26b2a2f07 100644 --- a/gopls/internal/test/marker/testdata/hover/basiclit.txt +++ b/gopls/internal/test/marker/testdata/hover/basiclit.txt @@ -1,10 +1,5 @@ This test checks gopls behavior when hovering over basic literals. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- basiclit.go -- package basiclit diff --git a/gopls/internal/test/marker/testdata/hover/const.txt b/gopls/internal/test/marker/testdata/hover/const.txt index c5f783c1f5d..179ff155357 100644 --- a/gopls/internal/test/marker/testdata/hover/const.txt +++ b/gopls/internal/test/marker/testdata/hover/const.txt @@ -1,10 +1,5 @@ This test checks hovering over constants. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/hover/godef.txt b/gopls/internal/test/marker/testdata/hover/godef.txt index 2d82ab0debe..9b2e7ec2ce3 100644 --- a/gopls/internal/test/marker/testdata/hover/godef.txt +++ b/gopls/internal/test/marker/testdata/hover/godef.txt @@ -3,6 +3,9 @@ It tests various hover and definition requests. Requires go1.19+ for the new go/doc/comment package. +TODO(adonovan): figure out why this test also fails +without -min_go=go1.20. Or just wait... + -- flags -- -min_go=go1.19 diff --git a/gopls/internal/test/marker/testdata/hover/goprivate.txt b/gopls/internal/test/marker/testdata/hover/goprivate.txt index f5b71795392..7269ba19634 100644 --- a/gopls/internal/test/marker/testdata/hover/goprivate.txt +++ b/gopls/internal/test/marker/testdata/hover/goprivate.txt @@ -1,10 +1,5 @@ This test checks that links in hover obey GOPRIVATE. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- env -- GOPRIVATE=mod.com -- go.mod -- diff --git a/gopls/internal/test/marker/testdata/hover/hover.txt b/gopls/internal/test/marker/testdata/hover/hover.txt index 32a4c195663..b5e4a88434b 100644 --- a/gopls/internal/test/marker/testdata/hover/hover.txt +++ b/gopls/internal/test/marker/testdata/hover/hover.txt @@ -1,10 +1,5 @@ This test demonstrates some features of the new marker test runner. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- a.go -- package a diff --git a/gopls/internal/test/marker/testdata/hover/linkable.txt b/gopls/internal/test/marker/testdata/hover/linkable.txt index b77b9e8a4d9..7fdb2470cdf 100644 --- a/gopls/internal/test/marker/testdata/hover/linkable.txt +++ b/gopls/internal/test/marker/testdata/hover/linkable.txt @@ -4,11 +4,6 @@ identifiers. We should only produce links that work, meaning the object is reachable via the package's public API. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/hover/linkable_generics.txt b/gopls/internal/test/marker/testdata/hover/linkable_generics.txt index 1ea009e0318..0b7ade7965e 100644 --- a/gopls/internal/test/marker/testdata/hover/linkable_generics.txt +++ b/gopls/internal/test/marker/testdata/hover/linkable_generics.txt @@ -1,10 +1,5 @@ This file contains tests for documentation links to generic code in hover. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/hover/linkname.txt b/gopls/internal/test/marker/testdata/hover/linkname.txt index 829097ce307..8bb2eeb33cd 100644 --- a/gopls/internal/test/marker/testdata/hover/linkname.txt +++ b/gopls/internal/test/marker/testdata/hover/linkname.txt @@ -1,10 +1,5 @@ This test check hover on the 2nd argument in go:linkname directives. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- go.mod -- module mod.com diff --git a/gopls/internal/test/marker/testdata/hover/std.txt b/gopls/internal/test/marker/testdata/hover/std.txt index af8f89fe65c..c0db135f6b1 100644 --- a/gopls/internal/test/marker/testdata/hover/std.txt +++ b/gopls/internal/test/marker/testdata/hover/std.txt @@ -7,11 +7,6 @@ synopsis does not. In the future we may need to limit this test to the latest Go version to avoid documentation churn. -Requires go1.19+ for the new go/doc/comment package. - --- flags -- --min_go=go1.19 - -- settings.json -- { "hoverKind": "SynopsisDocumentation" diff --git a/gopls/internal/test/marker/testdata/symbol/generic.txt b/gopls/internal/test/marker/testdata/symbol/generic.txt index 84cea99c1f7..1254851ad14 100644 --- a/gopls/internal/test/marker/testdata/symbol/generic.txt +++ b/gopls/internal/test/marker/testdata/symbol/generic.txt @@ -3,9 +3,6 @@ Basic tests of textDocument/documentSymbols with generics. -- symbol.go -- //@symbol(want) -//go:build go1.18 -// +build go1.18 - package main type T[P any] struct { diff --git a/gopls/internal/util/bug/bug.go b/gopls/internal/util/bug/bug.go index e04b753e315..dcd242d4856 100644 --- a/gopls/internal/util/bug/bug.go +++ b/gopls/internal/util/bug/bug.go @@ -19,7 +19,7 @@ import ( "sync" "time" - "golang.org/x/tools/gopls/internal/telemetry" + "golang.org/x/telemetry/counter" ) // PanicOnBugs controls whether to panic when bugs are reported. @@ -69,7 +69,7 @@ func Report(description string) { } // BugReportCount is a telemetry counter that tracks # of bug reports. -var BugReportCount = telemetry.NewStackCounter("gopls/bug", 16) +var BugReportCount = counter.NewStack("gopls/bug", 16) func report(description string) { _, file, line, ok := runtime.Caller(2) // all exported reporting functions call report directly diff --git a/gopls/internal/util/frob/frob.go b/gopls/internal/util/frob/frob.go index 0f3ede26773..cd385a9d692 100644 --- a/gopls/internal/util/frob/frob.go +++ b/gopls/internal/util/frob/frob.go @@ -93,7 +93,7 @@ func frobFor(t reflect.Type) *frob { case reflect.Array, reflect.Slice, - reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer + reflect.Pointer: fr.addElem(fr.t.Elem()) case reflect.Map: @@ -214,7 +214,7 @@ func (fr *frob) encode(out *writer, v reflect.Value) { } } - case reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer + case reflect.Pointer: if v.IsNil() { out.uint8(0) } else { @@ -341,7 +341,7 @@ func (fr *frob) decode(in *reader, addr reflect.Value) { } } - case reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer + case reflect.Pointer: isNil := in.uint8() == 0 if !isNil { ptr := reflect.New(fr.elems[0].t) @@ -402,38 +402,7 @@ func (r *reader) bytes(n int) []byte { type writer struct{ data []byte } func (w *writer) uint8(v uint8) { w.data = append(w.data, v) } -func (w *writer) uint16(v uint16) { w.data = appendUint16(w.data, v) } -func (w *writer) uint32(v uint32) { w.data = appendUint32(w.data, v) } -func (w *writer) uint64(v uint64) { w.data = appendUint64(w.data, v) } +func (w *writer) uint16(v uint16) { w.data = le.AppendUint16(w.data, v) } +func (w *writer) uint32(v uint32) { w.data = le.AppendUint32(w.data, v) } +func (w *writer) uint64(v uint64) { w.data = le.AppendUint64(w.data, v) } func (w *writer) bytes(v []byte) { w.data = append(w.data, v...) } - -// TODO(adonovan): delete these as in go1.19 they are methods on LittleEndian: - -func appendUint16(b []byte, v uint16) []byte { - return append(b, - byte(v), - byte(v>>8), - ) -} - -func appendUint32(b []byte, v uint32) []byte { - return append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - ) -} - -func appendUint64(b []byte, v uint64) []byte { - return append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - byte(v>>32), - byte(v>>40), - byte(v>>48), - byte(v>>56), - ) -} diff --git a/gopls/internal/util/lru/lru_fuzz_test.go b/gopls/internal/util/lru/lru_fuzz_test.go index 1733511f35e..b82776b25ba 100644 --- a/gopls/internal/util/lru/lru_fuzz_test.go +++ b/gopls/internal/util/lru/lru_fuzz_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package lru_test import ( diff --git a/gopls/internal/util/slices/slices.go b/gopls/internal/util/slices/slices.go index 4c4fa4d0a79..938ae6c34c0 100644 --- a/gopls/internal/util/slices/slices.go +++ b/gopls/internal/util/slices/slices.go @@ -6,14 +6,14 @@ package slices // Clone returns a copy of the slice. // The elements are copied using assignment, so this is a shallow clone. -// TODO(rfindley): use go1.19 slices.Clone. +// TODO(rfindley): use go1.21 slices.Clone. func Clone[S ~[]E, E any](s S) S { // The s[:0:0] preserves nil in case it matters. return append(s[:0:0], s...) } // Contains reports whether x is present in slice. -// TODO(adonovan): use go1.19 slices.Contains. +// TODO(adonovan): use go1.21 slices.Contains. func Contains[S ~[]E, E comparable](slice S, x E) bool { for _, elem := range slice { if elem == x { @@ -25,7 +25,7 @@ func Contains[S ~[]E, E comparable](slice S, x E) bool { // IndexFunc returns the first index i satisfying f(s[i]), // or -1 if none do. -// TODO(adonovan): use go1.19 slices.IndexFunc. +// TODO(adonovan): use go1.21 slices.IndexFunc. func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { for i := range s { if f(s[i]) { @@ -37,7 +37,7 @@ func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { // ContainsFunc reports whether at least one // element e of s satisfies f(e). -// TODO(adonovan): use go1.19 slices.ContainsFunc. +// TODO(adonovan): use go1.21 slices.ContainsFunc. func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool { return IndexFunc(s, f) >= 0 } @@ -63,7 +63,7 @@ func Concat[S ~[]E, E any](slices ...S) S { // another n elements. After Grow(n), at least n elements can be appended // to the slice without another allocation. If n is negative or too large to // allocate the memory, Grow panics. -// TODO(rfindley): use go1.19 slices.Grow. +// TODO(rfindley): use go1.21 slices.Grow. func Grow[S ~[]E, E any](s S, n int) S { if n < 0 { panic("cannot be negative") diff --git a/gopls/internal/vulncheck/scan/command.go b/gopls/internal/vulncheck/scan/command.go index 1f53d8b55f3..4ef005010c9 100644 --- a/gopls/internal/vulncheck/scan/command.go +++ b/gopls/internal/vulncheck/scan/command.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package scan import ( diff --git a/gopls/internal/vulncheck/semver/semver.go b/gopls/internal/vulncheck/semver/semver.go index 67c4fe8a39e..ade710d0573 100644 --- a/gopls/internal/vulncheck/semver/semver.go +++ b/gopls/internal/vulncheck/semver/semver.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - // Package semver provides shared utilities for manipulating // Go semantic versions. package semver diff --git a/gopls/internal/vulncheck/semver/semver_test.go b/gopls/internal/vulncheck/semver/semver_test.go index 6daead6855b..8a462287fa4 100644 --- a/gopls/internal/vulncheck/semver/semver_test.go +++ b/gopls/internal/vulncheck/semver/semver_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package semver import ( diff --git a/gopls/internal/vulncheck/vulntest/db.go b/gopls/internal/vulncheck/vulntest/db.go index 659d2f1fd10..e661b83bc71 100644 --- a/gopls/internal/vulncheck/vulntest/db.go +++ b/gopls/internal/vulncheck/vulntest/db.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - // Package vulntest provides helpers for vulncheck functionality testing. package vulntest diff --git a/gopls/internal/vulncheck/vulntest/db_test.go b/gopls/internal/vulncheck/vulntest/db_test.go index 22281249502..3c3407105ac 100644 --- a/gopls/internal/vulncheck/vulntest/db_test.go +++ b/gopls/internal/vulncheck/vulntest/db_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package vulntest import ( diff --git a/gopls/internal/vulncheck/vulntest/report.go b/gopls/internal/vulncheck/vulntest/report.go index cbfd0aeb8ff..b67986cf8c2 100644 --- a/gopls/internal/vulncheck/vulntest/report.go +++ b/gopls/internal/vulncheck/vulntest/report.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package vulntest import ( diff --git a/gopls/internal/vulncheck/vulntest/report_test.go b/gopls/internal/vulncheck/vulntest/report_test.go index 31f62aba838..b88633c2f1c 100644 --- a/gopls/internal/vulncheck/vulntest/report_test.go +++ b/gopls/internal/vulncheck/vulntest/report_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package vulntest import ( diff --git a/gopls/internal/vulncheck/vulntest/stdlib.go b/gopls/internal/vulncheck/vulntest/stdlib.go index 9bf4d4ef0d4..57194f71688 100644 --- a/gopls/internal/vulncheck/vulntest/stdlib.go +++ b/gopls/internal/vulncheck/vulntest/stdlib.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package vulntest import ( diff --git a/gopls/internal/vulncheck/vulntest/stdlib_test.go b/gopls/internal/vulncheck/vulntest/stdlib_test.go index 8f893f3ec42..7b212976350 100644 --- a/gopls/internal/vulncheck/vulntest/stdlib_test.go +++ b/gopls/internal/vulncheck/vulntest/stdlib_test.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package vulntest import "testing" diff --git a/gopls/main.go b/gopls/main.go index 31c5c5fdf1a..9217b278b1a 100644 --- a/gopls/main.go +++ b/gopls/main.go @@ -17,9 +17,9 @@ import ( "context" "os" + "golang.org/x/telemetry" "golang.org/x/tools/gopls/internal/cmd" "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/telemetry" versionpkg "golang.org/x/tools/gopls/internal/version" "golang.org/x/tools/internal/tool" ) @@ -29,7 +29,7 @@ var version = "" // if set by the linker, overrides the gopls version func main() { versionpkg.VersionOverride = version - telemetry.Start() + telemetry.Start(telemetry.Config{ReportCrashes: true}) ctx := context.Background() tool.Main(ctx, cmd.New(hooks.Options), os.Args[1:]) } diff --git a/internal/compat/appendf.go b/internal/compat/appendf.go deleted file mode 100644 index 069d5171704..00000000000 --- a/internal/compat/appendf.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2023 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. - -//go:build go1.19 - -package compat - -import "fmt" - -func Appendf(b []byte, format string, a ...interface{}) []byte { - return fmt.Appendf(b, format, a...) -} diff --git a/internal/compat/appendf_118.go b/internal/compat/appendf_118.go deleted file mode 100644 index 29af353cdaf..00000000000 --- a/internal/compat/appendf_118.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2023 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. - -//go:build !go1.19 - -package compat - -import "fmt" - -func Appendf(b []byte, format string, a ...interface{}) []byte { - return append(b, fmt.Sprintf(format, a...)...) -} diff --git a/internal/compat/doc.go b/internal/compat/doc.go deleted file mode 100644 index 59c667a37a2..00000000000 --- a/internal/compat/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2023 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. - -// The compat package implements API shims for backward compatibility at older -// Go versions. -package compat diff --git a/internal/gcimporter/gcimporter_test.go b/internal/gcimporter/gcimporter_test.go index 81d36bd5ff6..95cc36c4d96 100644 --- a/internal/gcimporter/gcimporter_test.go +++ b/internal/gcimporter/gcimporter_test.go @@ -11,7 +11,6 @@ import ( "bytes" "fmt" "go/ast" - "go/build" "go/constant" goimporter "go/importer" goparser "go/parser" @@ -165,8 +164,7 @@ func TestImportTypeparamTests(t *testing.T) { t.Skipf("in short mode, skipping test that requires export data for all of std") } - testenv.NeedsGo1Point(t, 18) // requires generics - testenv.NeedsGoBuild(t) // to find stdlib export data in the build cache + testenv.NeedsGoBuild(t) // to find stdlib export data in the build cache // This package only handles gc export data. if runtime.Compiler != "gc" { @@ -406,18 +404,6 @@ var importedObjectTests = []struct { {"go/types.Type", "type Type interface{String() string; Underlying() Type}"}, } -// TODO(rsc): Delete this init func after x/tools no longer needs to test successfully with Go 1.17. -func init() { - if build.Default.ReleaseTags[len(build.Default.ReleaseTags)-1] <= "go1.17" { - for i := range importedObjectTests { - if importedObjectTests[i].name == "context.Context" { - // Expand any to interface{}. - importedObjectTests[i].want = "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}" - } - } - } -} - func TestImportedTypes(t *testing.T) { // This package only handles gc export data. needsCompiler(t, "gc") @@ -739,8 +725,6 @@ func TestIssue25301(t *testing.T) { } func TestIssue51836(t *testing.T) { - testenv.NeedsGo1Point(t, 18) // requires generics - // This package only handles gc export data. needsCompiler(t, "gc") @@ -770,8 +754,6 @@ func TestIssue51836(t *testing.T) { } func TestIssue61561(t *testing.T) { - testenv.NeedsGo1Point(t, 18) // requires generics - const src = `package p type I[P any] interface { @@ -836,8 +818,6 @@ type K = StillBad[string] } func TestIssue57015(t *testing.T) { - testenv.NeedsGo1Point(t, 18) // requires generics - // This package only handles gc export data. needsCompiler(t, "gc") diff --git a/internal/gcimporter/iexport_go118_test.go b/internal/gcimporter/iexport_go118_test.go index 134c231f8c1..c748fb36165 100644 --- a/internal/gcimporter/iexport_go118_test.go +++ b/internal/gcimporter/iexport_go118_test.go @@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package gcimporter_test +// This file defines test of generics features introduce in go1.18. + import ( "bytes" "fmt" diff --git a/internal/gcimporter/support_go117.go b/internal/gcimporter/support_go117.go deleted file mode 100644 index d892273efb6..00000000000 --- a/internal/gcimporter/support_go117.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2021 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. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import "go/types" - -const iexportVersion = iexportVersionGo1_11 - -func additionalPredeclared() []types.Type { - return nil -} diff --git a/internal/gcimporter/support_go118.go b/internal/gcimporter/support_go118.go index edbe6ea7041..0cd3b91b65a 100644 --- a/internal/gcimporter/support_go118.go +++ b/internal/gcimporter/support_go118.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package gcimporter import "go/types" diff --git a/internal/gcimporter/unified_no.go b/internal/gcimporter/unified_no.go index 286bf445483..38b624cadab 100644 --- a/internal/gcimporter/unified_no.go +++ b/internal/gcimporter/unified_no.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !(go1.18 && goexperiment.unified) -// +build !go1.18 !goexperiment.unified +//go:build !goexperiment.unified +// +build !goexperiment.unified package gcimporter diff --git a/internal/gcimporter/unified_yes.go b/internal/gcimporter/unified_yes.go index b5d69ffbe68..b5118d0b3a5 100644 --- a/internal/gcimporter/unified_yes.go +++ b/internal/gcimporter/unified_yes.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 && goexperiment.unified -// +build go1.18,goexperiment.unified +//go:build goexperiment.unified +// +build goexperiment.unified package gcimporter diff --git a/internal/gcimporter/ureader_no.go b/internal/gcimporter/ureader_no.go deleted file mode 100644 index 8eb20729c2a..00000000000 --- a/internal/gcimporter/ureader_no.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2022 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. - -//go:build !go1.18 -// +build !go1.18 - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" -) - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") - return -} diff --git a/internal/gcimporter/ureader_yes.go b/internal/gcimporter/ureader_yes.go index bcf52d931df..f4edc46ab74 100644 --- a/internal/gcimporter/ureader_yes.go +++ b/internal/gcimporter/ureader_yes.go @@ -4,9 +4,6 @@ // Derived from go/internal/gcimporter/ureader.go -//go:build go1.18 -// +build go1.18 - package gcimporter import ( diff --git a/internal/imports/mod_test.go b/internal/imports/mod_test.go index c624463895d..e65104cbf2e 100644 --- a/internal/imports/mod_test.go +++ b/internal/imports/mod_test.go @@ -559,8 +559,6 @@ package v // Tests that go.work files are respected. func TestModWorkspace(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - mt := setup(t, nil, ` -- go.work -- go 1.18 @@ -595,8 +593,6 @@ package b // respected and that a wildcard replace in go.work overrides a versioned replace // in go.mod. func TestModWorkspaceReplace(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - mt := setup(t, nil, ` -- go.work -- use m @@ -654,8 +650,6 @@ func G() { // Tests a case where conflicting replaces are overridden by a replace // in the go.work file. func TestModWorkspaceReplaceOverride(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - mt := setup(t, nil, `-- go.work -- use m use n @@ -719,8 +713,6 @@ func G() { // workspaces with module pruning. This is based on the // cmd/go mod_prune_all script test. func TestModWorkspacePrune(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - mt := setup(t, nil, ` -- go.work -- go 1.18 diff --git a/internal/robustio/robustio_posix.go b/internal/robustio/robustio_posix.go index 8aa13d02786..cf74865d0b5 100644 --- a/internal/robustio/robustio_posix.go +++ b/internal/robustio/robustio_posix.go @@ -5,8 +5,6 @@ //go:build !windows && !plan9 // +build !windows,!plan9 -// TODO(adonovan): use 'unix' tag when go1.19 can be assumed. - package robustio import ( diff --git a/internal/tokeninternal/tokeninternal.go b/internal/tokeninternal/tokeninternal.go index 7e638ec24fc..ff9437a36cd 100644 --- a/internal/tokeninternal/tokeninternal.go +++ b/internal/tokeninternal/tokeninternal.go @@ -34,30 +34,16 @@ func GetLines(file *token.File) []int { lines []int _ []struct{} } - type tokenFile118 struct { - _ *token.FileSet // deleted in go1.19 - tokenFile119 - } - - type uP = unsafe.Pointer - switch unsafe.Sizeof(*file) { - case unsafe.Sizeof(tokenFile118{}): - var ptr *tokenFile118 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - case unsafe.Sizeof(tokenFile119{}): - var ptr *tokenFile119 - *(*uP)(uP(&ptr)) = uP(file) - ptr.mu.Lock() - defer ptr.mu.Unlock() - return ptr.lines - - default: + if unsafe.Sizeof(*file) != unsafe.Sizeof(tokenFile119{}) { panic("unexpected token.File size") } + var ptr *tokenFile119 + type uP = unsafe.Pointer + *(*uP)(uP(&ptr)) = uP(file) + ptr.mu.Lock() + defer ptr.mu.Unlock() + return ptr.lines } // AddExistingFiles adds the specified files to the FileSet if they diff --git a/internal/typeparams/common.go b/internal/typeparams/common.go index 6679d79f9cf..8c3a42dc311 100644 --- a/internal/typeparams/common.go +++ b/internal/typeparams/common.go @@ -2,20 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package typeparams contains common utilities for writing tools that interact -// with generic Go code, as introduced with Go 1.18. -// -// Many of the types and functions in this package are proxies for the new APIs -// introduced in the standard library with Go 1.18. For example, the -// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec -// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go -// versions older than 1.18 these helpers are implemented as stubs, allowing -// users of this package to write code that handles generic constructs inline, -// even if the Go version being used to compile does not support generics. -// -// Additionally, this package contains common utilities for working with the -// new generic constructs, to supplement the standard library APIs. Notably, -// the StructuralTerms API computes a minimal representation of the structural +// Package typeparams contains common utilities for writing tools that +// interact with generic Go code, as introduced with Go 1.18. It +// supplements the standard library APIs. Notably, the StructuralTerms +// API computes a minimal representation of the structural // restrictions on a type parameter. // // An external version of these APIs is available in the diff --git a/internal/typeparams/common_test.go b/internal/typeparams/common_test.go index b6f355cc5d7..b095b65e808 100644 --- a/internal/typeparams/common_test.go +++ b/internal/typeparams/common_test.go @@ -11,7 +11,6 @@ import ( "go/types" "testing" - "golang.org/x/tools/internal/testenv" . "golang.org/x/tools/internal/typeparams" ) @@ -41,7 +40,6 @@ func TestGetIndexExprData(t *testing.T) { } func TestOriginMethodRecursive(t *testing.T) { - testenv.NeedsGo1Point(t, 18) src := `package p type N[A any] int @@ -113,7 +111,6 @@ func (r *N[C]) n() { } } func TestOriginMethodUses(t *testing.T) { - testenv.NeedsGo1Point(t, 18) tests := []string{ `type T interface { m() }; func _(t T) { t.m() }`, @@ -209,8 +206,6 @@ func TestOriginMethod60628(t *testing.T) { } func TestGenericAssignableTo(t *testing.T) { - testenv.NeedsGo1Point(t, 18) - tests := []struct { src string want bool diff --git a/internal/typesinternal/types_118.go b/internal/typesinternal/types_118.go index a42b072a67d..ef7ea290c0b 100644 --- a/internal/typesinternal/types_118.go +++ b/internal/typesinternal/types_118.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.18 -// +build go1.18 - package typesinternal import (