diff --git a/internal/lsp/cache/debug.go b/internal/lsp/cache/debug.go index ca8b7c866e..d665b011da 100644 --- a/internal/lsp/cache/debug.go +++ b/internal/lsp/cache/debug.go @@ -23,7 +23,7 @@ func debugf(format string, args ...interface{}) { return } if false { - fmt.Sprintf(format, args...) // encourage vet to validate format strings + _ = fmt.Sprintf(format, args...) // encourage vet to validate format strings } fmt.Fprintf(os.Stderr, ">>> "+format+"\n", args...) } diff --git a/internal/lsp/cmd/test/definition.go b/internal/lsp/cmd/test/definition.go index c82d9a6c1a..9c49eaa7d5 100644 --- a/internal/lsp/cmd/test/definition.go +++ b/internal/lsp/cmd/test/definition.go @@ -10,8 +10,6 @@ import ( "strings" "testing" - "golang.org/x/tools/internal/lsp/diff" - "golang.org/x/tools/internal/lsp/diff/myers" "golang.org/x/tools/internal/lsp/tests" "golang.org/x/tools/internal/span" ) @@ -51,11 +49,7 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) { return []byte(got), nil }))) if expect != "" && !strings.HasPrefix(got, expect) { - d, err := myers.ComputeEdits("", expect, got) - if err != nil { - t.Fatal(err) - } - t.Errorf("definition %v failed with %#v\n%s", tag, args, diff.ToUnified("expect", "got", expect, d)) + tests.CheckSameMarkdown(t, got, expect) } } } diff --git a/internal/lsp/lsp_test.go b/internal/lsp/lsp_test.go index 53890dc616..5d37c56a8e 100644 --- a/internal/lsp/lsp_test.go +++ b/internal/lsp/lsp_test.go @@ -739,7 +739,7 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) { got := tests.StripSubscripts(hover.Contents.Value) expectHover = tests.StripSubscripts(expectHover) if got != expectHover { - t.Errorf("%s:\n%s", d.Src, tests.Diff(t, expectHover, got)) + tests.CheckSameMarkdown(t, got, expectHover) } } if !d.OnlyHover { diff --git a/internal/lsp/source/comment.go b/internal/lsp/source/comment.go index 000d6136c8..ff6d11f4ff 100644 --- a/internal/lsp/source/comment.go +++ b/internal/lsp/source/comment.go @@ -2,6 +2,9 @@ // 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 source import ( @@ -226,7 +229,7 @@ func unindent(block []string) { prefix := block[0][0:indentLen(block[0])] for _, line := range block { if !isBlank(line) { - prefix = commonPrefix(prefix, line[0:indentLen(line)]) + prefix = commonPrefix(prefix, line) } } n := len(prefix) diff --git a/internal/lsp/source/comment_go118.go b/internal/lsp/source/comment_go118.go new file mode 100644 index 0000000000..0503670d3b --- /dev/null +++ b/internal/lsp/source/comment_go118.go @@ -0,0 +1,37 @@ +// 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 source + +// 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. (cmd/test/definition.go, source/comment_test.go, +// and source/source_test.go) Each of the test files checks the results +// with a function, tests.CheckSameMarkdown, that accepts both the old and the new +// results. (The old code escapes many characters the new code does not, +// and the new code sometimes adds a blank line.) + +// 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 "go/doc/comment" + +// 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) string { + var p comment.Parser + doc := p.Parse(text) + var pr comment.Printer + easy := pr.Markdown(doc) + return string(easy) +} diff --git a/internal/lsp/source/comment_test.go b/internal/lsp/source/comment_go118_test.go similarity index 99% rename from internal/lsp/source/comment_test.go rename to internal/lsp/source/comment_go118_test.go index 9efde16ef3..b48b2e753c 100644 --- a/internal/lsp/source/comment_test.go +++ b/internal/lsp/source/comment_go118_test.go @@ -2,6 +2,9 @@ // 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 source import ( diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go index d2f80c793b..6ad458ba4c 100644 --- a/internal/lsp/source/hover.go +++ b/internal/lsp/source/hover.go @@ -797,12 +797,8 @@ func FormatHover(h *HoverJSON, options *Options) (string, error) { if el != "" { b.WriteString(el) - // Don't write out final newline. - if i == len(parts) { - continue - } // If any elements of the remainder of the list are non-empty, - // write a newline. + // write an extra newline. if anyNonEmpty(parts[i+1:]) { if options.PreferredContentFormat == protocol.Markdown { b.WriteString("\n\n") diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go index 5fdcc0f86e..177b85d13a 100644 --- a/internal/lsp/source/source_test.go +++ b/internal/lsp/source/source_test.go @@ -584,7 +584,8 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) { hover = tests.StripSubscripts(hover) expectHover = tests.StripSubscripts(expectHover) if hover != expectHover { - t.Errorf("hoverdef for %s failed:\n%s", d.Src, tests.Diff(t, expectHover, hover)) + tests.CheckSameMarkdown(t, hover, expectHover) + } } if !d.OnlyHover { diff --git a/internal/lsp/testdata/godef/a/a.go.golden b/internal/lsp/testdata/godef/a/a.go.golden index 819262672a..7f114e54b0 100644 --- a/internal/lsp/testdata/godef/a/a.go.golden +++ b/internal/lsp/testdata/godef/a/a.go.golden @@ -3,7 +3,8 @@ func (*sync.Mutex).Lock() ``` -Lock locks m\. +Lock locks m. + [`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock) -- Name-hoverdef -- @@ -11,7 +12,8 @@ Lock locks m\. func (*types.object).Name() string ``` -Name returns the object\'s \(package\-local, unqualified\) name\. +Name returns the object's (package-local, unqualified) name. + [`(types.TypeName).Name` on pkg.go.dev](https://pkg.go.dev/go/types#TypeName.Name) -- Random-definition -- @@ -75,7 +77,8 @@ func Random2(y int) int [`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2) -- aPackage-hoverdef -- -Package a is a package for testing go to definition\. +Package a is a package for testing go to definition. + -- declBlockA-hoverdef -- ```go type a struct { @@ -84,12 +87,14 @@ type a struct { ``` 1st type declaration block + -- declBlockB-hoverdef -- ```go type b struct{} ``` b has a comment + -- declBlockC-hoverdef -- ```go type c struct { @@ -98,12 +103,14 @@ type c struct { ``` c is a struct + -- declBlockD-hoverdef -- ```go type d string ``` 3rd type declaration block + -- declBlockE-hoverdef -- ```go type e struct { @@ -112,12 +119,13 @@ type e struct { ``` e has a comment + -- err-definition -- godef/a/a.go:33:6-9: defined here as ```go var err error ``` -\@err +@err -- err-definition-json -- { "span": { @@ -133,7 +141,7 @@ var err error "offset": 615 } }, - "description": "```go\nvar err error\n```\n\n\\@err" + "description": "```go\nvar err error\n```\n\n@err" } -- err-hoverdef -- @@ -141,25 +149,29 @@ var err error var err error ``` -\@err +@err + -- g-hoverdef -- ```go const g untyped int = 1 ``` -When I hover on g, I should see this comment\. +When I hover on g, I should see this comment. + -- h-hoverdef -- ```go const h untyped int = 2 ``` -Constant block\. +Constant block. + -- make-hoverdef -- ```go func make(t Type, size ...int) Type ``` -The make built\-in function allocates and initializes an object of type slice, map, or chan \(only\)\. +The make built-in function allocates and initializes an object of type slice, map, or chan (only). + [`make` on pkg.go.dev](https://pkg.go.dev/builtin#make) -- string-hoverdef -- @@ -167,7 +179,8 @@ The make built\-in function allocates and initializes an object of type slice, m type string string ``` -string is the set of all strings of 8\-bit bytes, conventionally but not necessarily representing UTF\-8\-encoded text\. +string is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8-encoded text. + [`string` on pkg.go.dev](https://pkg.go.dev/builtin#string) -- typesImport-hoverdef -- @@ -181,10 +194,12 @@ package types ("go/types") var x string ``` -x is a variable\. +x is a variable. + -- z-hoverdef -- ```go var z string ``` -z is a variable too\. +z is a variable too. + diff --git a/internal/lsp/testdata/godef/a/d.go.golden b/internal/lsp/testdata/godef/a/d.go.golden index 7577b556b8..9f04317c00 100644 --- a/internal/lsp/testdata/godef/a/d.go.golden +++ b/internal/lsp/testdata/godef/a/d.go.golden @@ -3,7 +3,8 @@ godef/a/d.go:6:2-8: defined here as ```go field Member string ``` -\@Member +@Member + [`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member) -- Member-definition-json -- @@ -21,7 +22,7 @@ field Member string "offset": 96 } }, - "description": "```go\nfield Member string\n```\n\n\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)" + "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)" } -- Member-hoverdef -- @@ -29,7 +30,8 @@ field Member string field Member string ``` -\@Member +@Member + [`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member) -- Method-definition -- @@ -67,7 +69,8 @@ godef/a/d.go:9:5-10: defined here as ```go var Other Thing ``` -\@Other +@Other + [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other) -- Other-definition-json -- @@ -85,7 +88,7 @@ var Other Thing "offset": 126 } }, - "description": "```go\nvar Other Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)" + "description": "```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)" } -- Other-hoverdef -- @@ -93,7 +96,8 @@ var Other Thing var Other Thing ``` -\@Other +@Other + [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other) -- Thing-definition -- @@ -161,4 +165,5 @@ func Things(val []string) []Thing [`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things) -- a-hoverdef -- -Package a is a package for testing go to definition\. +Package a is a package for testing go to definition. + diff --git a/internal/lsp/testdata/godef/a/g.go.golden b/internal/lsp/testdata/godef/a/g.go.golden index b7ed739280..f7a2e1b077 100644 --- a/internal/lsp/testdata/godef/a/g.go.golden +++ b/internal/lsp/testdata/godef/a/g.go.golden @@ -3,4 +3,5 @@ const dur time.Duration = 910350000000 // 15m10.35s ``` -dur is a constant of type time\.Duration\. +dur is a constant of type time.Duration. + diff --git a/internal/lsp/testdata/godef/a/h.go.golden b/internal/lsp/testdata/godef/a/h.go.golden index 4b27211e9a..295876647a 100644 --- a/internal/lsp/testdata/godef/a/h.go.golden +++ b/internal/lsp/testdata/godef/a/h.go.golden @@ -4,42 +4,49 @@ field d int ``` d field + -- arrE-hoverdef -- ```go field e struct{f int} ``` e nested struct + -- arrF-hoverdef -- ```go field f int ``` f field of nested struct + -- complexH-hoverdef -- ```go field h int ``` h field + -- complexI-hoverdef -- ```go field i struct{j int} ``` i nested struct + -- complexJ-hoverdef -- ```go field j int ``` j field of nested struct + -- mapStructKeyX-hoverdef -- ```go field x []string ``` X key field + -- mapStructKeyY-hoverdef -- ```go field y string @@ -50,87 +57,102 @@ field x string ``` X value field + -- nestedMap-hoverdef -- ```go field m map[string]float64 ``` nested map + -- nestedNumber-hoverdef -- ```go field number int64 ``` nested number + -- nestedString-hoverdef -- ```go field str string ``` nested string + -- openMethod-hoverdef -- ```go func (interface).open() error ``` open method comment + -- returnX-hoverdef -- ```go field x int ``` X coord + -- returnY-hoverdef -- ```go field y int ``` Y coord + -- structA-hoverdef -- ```go field a int ``` a field + -- structB-hoverdef -- ```go field b struct{c int} ``` b nested struct + -- structC-hoverdef -- ```go field c int ``` c field of nested struct + -- testDescription-hoverdef -- ```go field desc string ``` test description + -- testInput-hoverdef -- ```go field in map[string][]struct{key string; value interface{}} ``` test input + -- testInputKey-hoverdef -- ```go field key string ``` test key + -- testInputValue-hoverdef -- ```go field value interface{} ``` test value + -- testResultValue-hoverdef -- ```go field value int ``` expected test value + diff --git a/internal/lsp/testdata/godef/a/random.go.golden b/internal/lsp/testdata/godef/a/random.go.golden index e8b180a4b4..eb70a515f1 100644 --- a/internal/lsp/testdata/godef/a/random.go.golden +++ b/internal/lsp/testdata/godef/a/random.go.golden @@ -33,7 +33,7 @@ godef/a/random.go:13:2-3: defined here as ```go field x int ``` -\@mark\(PosX, \"x\"\),mark\(PosY, \"y\"\) +@mark(PosX, "x"),mark(PosY, "y") -- PosX-definition-json -- { "span": { @@ -49,7 +49,7 @@ field x int "offset": 188 } }, - "description": "```go\nfield x int\n```\n\n\\@mark\\(PosX, \\\"x\\\"\\),mark\\(PosY, \\\"y\\\"\\)" + "description": "```go\nfield x int\n```\n\n@mark(PosX, \"x\"),mark(PosY, \"y\")" } -- PosX-hoverdef -- @@ -57,7 +57,8 @@ field x int field x int ``` -\@mark\(PosX, \"x\"\),mark\(PosY, \"y\"\) +@mark(PosX, "x"),mark(PosY, "y") + -- RandomParamY-definition -- godef/a/random.go:8:14-15: defined here as ```go var y int diff --git a/internal/lsp/testdata/godef/b/b.go.golden b/internal/lsp/testdata/godef/b/b.go.golden index a30b3f70b5..073d633ce3 100644 --- a/internal/lsp/testdata/godef/b/b.go.golden +++ b/internal/lsp/testdata/godef/b/b.go.golden @@ -3,7 +3,8 @@ func (a.I).B() ``` -\@mark\(AB, \"B\"\) +@mark(AB, "B") + [`(a.I).B` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#I.B) -- AField-hoverdef -- @@ -11,7 +12,8 @@ func (a.I).B() field Field int ``` -\@mark\(AField, \"Field\"\) +@mark(AField, "Field") + [`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#S.Field) -- AField2-hoverdef -- @@ -19,7 +21,8 @@ field Field int field Field2 int ``` -\@mark\(AField2, \"Field2\"\) +@mark(AField2, "Field2") + [`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#R.Field2) -- AGoodbye-hoverdef -- @@ -27,7 +30,8 @@ field Field2 int func (a.H).Goodbye() ``` -\@mark\(AGoodbye, \"Goodbye\"\) +@mark(AGoodbye, "Goodbye") + [`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#H.Goodbye) -- AHello-hoverdef -- @@ -35,7 +39,8 @@ func (a.H).Goodbye() func (a.J).Hello() ``` -\@mark\(AHello, \"Hello\"\) +@mark(AHello, "Hello") + [`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#J.Hello) -- AHey-hoverdef -- @@ -85,7 +90,8 @@ godef/a/a.go:26:6-7: defined here as ```go type A string ``` -\@mark\(AString, \"A\"\) +@mark(AString, "A") + [`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A) -- AString-definition-json -- @@ -103,7 +109,7 @@ type A string "offset": 468 } }, - "description": "```go\ntype A string\n```\n\n\\@mark\\(AString, \\\"A\\\"\\)\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)" + "description": "```go\ntype A string\n```\n\n@mark(AString, \"A\")\n\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)" } -- AString-hoverdef -- @@ -111,7 +117,8 @@ type A string type A string ``` -\@mark\(AString, \"A\"\) +@mark(AString, "A") + [`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A) -- AStuff-definition -- @@ -189,7 +196,8 @@ godef/b/b.go:28:2-4: defined here as ```go field F1 int ``` -\@mark\(S1F1, \"F1\"\) +@mark(S1F1, "F1") + [`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1) -- S1F1-definition-json -- @@ -207,7 +215,7 @@ field F1 int "offset": 608 } }, - "description": "```go\nfield F1 int\n```\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)" + "description": "```go\nfield F1 int\n```\n\n@mark(S1F1, \"F1\")\n\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)" } -- S1F1-hoverdef -- @@ -215,7 +223,8 @@ field F1 int field F1 int ``` -\@mark\(S1F1, \"F1\"\) +@mark(S1F1, "F1") + [`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1) -- S1S2-definition -- @@ -223,7 +232,8 @@ godef/b/b.go:29:2-4: defined here as ```go field S2 S2 ``` -\@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\) +@godef("S2", S2),mark(S1S2, "S2") + [`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2) -- S1S2-definition-json -- @@ -241,7 +251,7 @@ field S2 S2 "offset": 640 } }, - "description": "```go\nfield S2 S2\n```\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)" + "description": "```go\nfield S2 S2\n```\n\n@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)" } -- S1S2-hoverdef -- @@ -249,7 +259,8 @@ field S2 S2 field S2 S2 ``` -\@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\) +@godef("S2", S2),mark(S1S2, "S2") + [`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2) -- S2-definition -- @@ -295,7 +306,8 @@ godef/b/b.go:35:2-4: defined here as ```go field F1 string ``` -\@mark\(S2F1, \"F1\"\) +@mark(S2F1, "F1") + [`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1) -- S2F1-definition-json -- @@ -313,7 +325,7 @@ field F1 string "offset": 783 } }, - "description": "```go\nfield F1 string\n```\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)" + "description": "```go\nfield F1 string\n```\n\n@mark(S2F1, \"F1\")\n\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)" } -- S2F1-hoverdef -- @@ -321,7 +333,8 @@ field F1 string field F1 string ``` -\@mark\(S2F1, \"F1\"\) +@mark(S2F1, "F1") + [`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1) -- S2F2-definition -- @@ -329,7 +342,8 @@ godef/b/b.go:36:2-4: defined here as ```go field F2 int ``` -\@mark\(S2F2, \"F2\"\) +@mark(S2F2, "F2") + [`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2) -- S2F2-definition-json -- @@ -347,7 +361,7 @@ field F2 int "offset": 816 } }, - "description": "```go\nfield F2 int\n```\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)" + "description": "```go\nfield F2 int\n```\n\n@mark(S2F2, \"F2\")\n\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)" } -- S2F2-hoverdef -- @@ -355,7 +369,8 @@ field F2 int field F2 int ``` -\@mark\(S2F2, \"F2\"\) +@mark(S2F2, "F2") + [`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2) -- aAlias-definition -- @@ -363,7 +378,7 @@ godef/b/b.go:25:6-12: defined here as ```go type aAlias = a.A ``` -\@mark\(aAlias, \"aAlias\"\) +@mark(aAlias, "aAlias") -- aAlias-definition-json -- { "span": { @@ -379,7 +394,7 @@ type aAlias = a.A "offset": 548 } }, - "description": "```go\ntype aAlias = a.A\n```\n\n\\@mark\\(aAlias, \\\"aAlias\\\"\\)" + "description": "```go\ntype aAlias = a.A\n```\n\n@mark(aAlias, \"aAlias\")" } -- aAlias-hoverdef -- @@ -387,13 +402,15 @@ type aAlias = a.A type aAlias = a.A ``` -\@mark\(aAlias, \"aAlias\"\) +@mark(aAlias, "aAlias") + -- bX-definition -- godef/b/b.go:57:7-8: defined here as ```go const X untyped int = 0 ``` -\@mark\(bX, \"X\"\),godef\(\"X\", bX\) +@mark(bX, "X"),godef("X", bX) + [`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X) -- bX-definition-json -- @@ -411,7 +428,7 @@ const X untyped int = 0 "offset": 1250 } }, - "description": "```go\nconst X untyped int = 0\n```\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)" + "description": "```go\nconst X untyped int = 0\n```\n\n@mark(bX, \"X\"),godef(\"X\", bX)\n\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)" } -- bX-hoverdef -- @@ -419,7 +436,8 @@ const X untyped int = 0 const X untyped int = 0 ``` -\@mark\(bX, \"X\"\),godef\(\"X\", bX\) +@mark(bX, "X"),godef("X", bX) + [`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X) -- myFoo-definition -- diff --git a/internal/lsp/testdata/godef/b/c.go.golden b/internal/lsp/testdata/godef/b/c.go.golden index fddf3d273c..a48dbd2b88 100644 --- a/internal/lsp/testdata/godef/b/c.go.golden +++ b/internal/lsp/testdata/godef/b/c.go.golden @@ -43,7 +43,8 @@ godef/b/b.go:28:2-4: defined here as ```go field F1 int ``` -\@mark\(S1F1, \"F1\"\) +@mark(S1F1, "F1") + [`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1) -- S1F1-definition-json -- @@ -61,7 +62,7 @@ field F1 int "offset": 608 } }, - "description": "```go\nfield F1 int\n```\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)" + "description": "```go\nfield F1 int\n```\n\n@mark(S1F1, \"F1\")\n\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)" } -- S1F1-hoverdef -- @@ -69,6 +70,7 @@ field F1 int field F1 int ``` -\@mark\(S1F1, \"F1\"\) +@mark(S1F1, "F1") + [`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1) diff --git a/internal/lsp/testdata/godef/b/e.go.golden b/internal/lsp/testdata/godef/b/e.go.golden index 5a26caa4fe..d03b6728a4 100644 --- a/internal/lsp/testdata/godef/b/e.go.golden +++ b/internal/lsp/testdata/godef/b/e.go.golden @@ -3,7 +3,8 @@ godef/a/d.go:6:2-8: defined here as ```go field Member string ``` -\@Member +@Member + [`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member) -- Member-definition-json -- @@ -21,7 +22,7 @@ field Member string "offset": 96 } }, - "description": "```go\nfield Member string\n```\n\n\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)" + "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)" } -- Member-hoverdef -- @@ -29,7 +30,8 @@ field Member string field Member string ``` -\@Member +@Member + [`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member) -- Other-definition -- @@ -37,7 +39,8 @@ godef/a/d.go:9:5-10: defined here as ```go var a.Other a.Thing ``` -\@Other +@Other + [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other) -- Other-definition-json -- @@ -55,7 +58,7 @@ var a.Other a.Thing "offset": 126 } }, - "description": "```go\nvar a.Other a.Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)" + "description": "```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)" } -- Other-hoverdef -- @@ -63,7 +66,8 @@ var a.Other a.Thing var a.Other a.Thing ``` -\@Other +@Other + [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other) -- Thing-definition -- diff --git a/internal/lsp/testdata/godef/b/h.go.golden b/internal/lsp/testdata/godef/b/h.go.golden index 73593c63da..08a15395e9 100644 --- a/internal/lsp/testdata/godef/b/h.go.golden +++ b/internal/lsp/testdata/godef/b/h.go.golden @@ -9,4 +9,5 @@ func AStuff() var _ A ``` -variable of type a\.A +variable of type a.A + diff --git a/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/internal/lsp/testdata/godef/broken/unclosedIf.go.golden index 5c3329d8b6..9ce869848c 100644 --- a/internal/lsp/testdata/godef/broken/unclosedIf.go.golden +++ b/internal/lsp/testdata/godef/broken/unclosedIf.go.golden @@ -3,7 +3,7 @@ godef/broken/unclosedIf.go:7:7-19: defined here as ```go var myUnclosedIf string ``` -\@myUnclosedIf +@myUnclosedIf -- myUnclosedIf-definition-json -- { "span": { @@ -19,7 +19,7 @@ var myUnclosedIf string "offset": 80 } }, - "description": "```go\nvar myUnclosedIf string\n```\n\n\\@myUnclosedIf" + "description": "```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf" } -- myUnclosedIf-hoverdef -- @@ -27,4 +27,5 @@ var myUnclosedIf string var myUnclosedIf string ``` -\@myUnclosedIf +@myUnclosedIf + diff --git a/internal/lsp/testdata/godef/hover_generics/hover.go.golden b/internal/lsp/testdata/godef/hover_generics/hover.go.golden index 91981a1177..dad9d343bd 100644 --- a/internal/lsp/testdata/godef/hover_generics/hover.go.golden +++ b/internal/lsp/testdata/godef/hover_generics/hover.go.golden @@ -11,7 +11,8 @@ type parameter P interface{~int|string} field Q int ``` -\@mark\(ValueQfield, \"Q\"\),hoverdef\(\"Q\", ValueQfield\) +@mark(ValueQfield, "Q"),hoverdef("Q", ValueQfield) + [`(hover.Value).Q` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/hover_generics#Value.Q) -- ValueTdecl-hoverdef -- @@ -34,7 +35,8 @@ type value[T any] struct { field Q int ``` -\@mark\(valueQfield, \"Q\"\),hoverdef\(\"Q\", valueQfield\) +@mark(valueQfield, "Q"),hoverdef("Q", valueQfield) + -- valueTdecl-hoverdef -- ```go type parameter T any diff --git a/internal/lsp/tests/metadata_go118.go b/internal/lsp/tests/metadata_go118.go new file mode 100644 index 0000000000..3d9748b4e3 --- /dev/null +++ b/internal/lsp/tests/metadata_go118.go @@ -0,0 +1,116 @@ +// 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 tests + +import ( + "testing" +) + +// The markdown in the golden files matches the converter in comment.go, +// but for go1.19 and later the conversion is done using go/doc/comment. +// Compared to the newer version, the older version +// has extra escapes, and treats code blocks slightly differently. +func CheckSameMarkdown(t *testing.T, got, want string) { + t.Helper() + for _, dd := range markDiffs { + if got == dd.v18 && want == dd.v19 { + return + } + } + t.Errorf("got %q want %q", got, want) +} + +type markDiff struct { + v18, v19 string +} + +var markDiffs = []markDiff{{v19: "Package a is a package for testing go to definition.\n", v18: "Package a is a package for testing go to definition\\."}, + {v19: "```go\nconst X untyped int = 0\n```\n\n@mark(bX, \"X\"),godef(\"X\", bX)\n\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)", v18: "```go\nconst X untyped int = 0\n```\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)"}, + {v19: "```go\nconst dur time.Duration = 910350000000 // 15m10.35s\n```\n\ndur is a constant of type time.Duration.\n", v18: "```go\nconst dur time.Duration = 910350000000 // 15m10.35s\n```\n\ndur is a constant of type time\\.Duration\\."}, + {v19: "```go\nconst g untyped int = 1\n```\n\nWhen I hover on g, I should see this comment.\n", v18: "```go\nconst g untyped int = 1\n```\n\nWhen I hover on g, I should see this comment\\."}, + {v19: "```go\nconst h untyped int = 2\n```\n\nConstant block.\n", v18: "```go\nconst h untyped int = 2\n```\n\nConstant block\\."}, + {v19: "```go\nfield F1 int\n```\n\n@mark(S1F1, \"F1\")\n\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)", v18: "```go\nfield F1 int\n```\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)"}, + {v19: "```go\nfield F1 string\n```\n\n@mark(S2F1, \"F1\")\n\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)", v18: "```go\nfield F1 string\n```\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)"}, + {v19: "```go\nfield F2 int\n```\n\n@mark(S2F2, \"F2\")\n\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)", v18: "```go\nfield F2 int\n```\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)"}, + {v19: "```go\nfield Field int\n```\n\n@mark(AField, \"Field\")\n\n\n[`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#S.Field)", v18: "```go\nfield Field int\n```\n\n\\@mark\\(AField, \\\"Field\\\"\\)\n\n[`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#S.Field)"}, + {v19: "```go\nfield Field2 int\n```\n\n@mark(AField2, \"Field2\")\n\n\n[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#R.Field2)", v18: "```go\nfield Field2 int\n```\n\n\\@mark\\(AField2, \\\"Field2\\\"\\)\n\n[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#R.Field2)"}, + {v19: "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)", v18: "```go\nfield Member string\n```\n\n\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)"}, + {v19: "```go\nfield Q int\n```\n\n@mark(ValueQfield, \"Q\"),hoverdef(\"Q\", ValueQfield)\n\n\n[`(hover.Value).Q` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/hover_generics#Value.Q)", v18: "```go\nfield Q int\n```\n\n\\@mark\\(ValueQfield, \\\"Q\\\"\\),hoverdef\\(\\\"Q\\\", ValueQfield\\)\n\n[`(hover.Value).Q` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/hover_generics#Value.Q)"}, + {v19: "```go\nfield Q int\n```\n\n@mark(valueQfield, \"Q\"),hoverdef(\"Q\", valueQfield)\n", v18: "```go\nfield Q int\n```\n\n\\@mark\\(valueQfield, \\\"Q\\\"\\),hoverdef\\(\\\"Q\\\", valueQfield\\)"}, + {v19: "```go\nfield S2 S2\n```\n\n@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)", v18: "```go\nfield S2 S2\n```\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)"}, + {v19: "```go\nfield a int\n```\n\na field\n", v18: "```go\nfield a int\n```\n\na field"}, + {v19: "```go\nfield b struct{c int}\n```\n\nb nested struct\n", v18: "```go\nfield b struct{c int}\n```\n\nb nested struct"}, + {v19: "```go\nfield c int\n```\n\nc field of nested struct\n", v18: "```go\nfield c int\n```\n\nc field of nested struct"}, + {v19: "```go\nfield d int\n```\n\nd field\n", v18: "```go\nfield d int\n```\n\nd field"}, + {v19: "```go\nfield desc string\n```\n\ntest description\n", v18: "```go\nfield desc string\n```\n\ntest description"}, + {v19: "```go\nfield e struct{f int}\n```\n\ne nested struct\n", v18: "```go\nfield e struct{f int}\n```\n\ne nested struct"}, + {v19: "```go\nfield f int\n```\n\nf field of nested struct\n", v18: "```go\nfield f int\n```\n\nf field of nested struct"}, + {v19: "```go\nfield h int\n```\n\nh field\n", v18: "```go\nfield h int\n```\n\nh field"}, + {v19: "```go\nfield i struct{j int}\n```\n\ni nested struct\n", v18: "```go\nfield i struct{j int}\n```\n\ni nested struct"}, + {v19: "```go\nfield in map[string][]struct{key string; value interface{}}\n```\n\ntest input\n", v18: "```go\nfield in map[string][]struct{key string; value interface{}}\n```\n\ntest input"}, + {v19: "```go\nfield j int\n```\n\nj field of nested struct\n", v18: "```go\nfield j int\n```\n\nj field of nested struct"}, + {v19: "```go\nfield key string\n```\n\ntest key\n", v18: "```go\nfield key string\n```\n\ntest key"}, + {v19: "```go\nfield m map[string]float64\n```\n\nnested map\n", v18: "```go\nfield m map[string]float64\n```\n\nnested map"}, + {v19: "```go\nfield number int64\n```\n\nnested number\n", v18: "```go\nfield number int64\n```\n\nnested number"}, + {v19: "```go\nfield str string\n```\n\nnested string\n", v18: "```go\nfield str string\n```\n\nnested string"}, + {v19: "```go\nfield value int\n```\n\nexpected test value\n", v18: "```go\nfield value int\n```\n\nexpected test value"}, + {v19: "```go\nfield value interface{}\n```\n\ntest value\n", v18: "```go\nfield value interface{}\n```\n\ntest value"}, + {v19: "```go\nfield x []string\n```\n\nX key field\n", v18: "```go\nfield x []string\n```\n\nX key field"}, + {v19: "```go\nfield x int\n```\n\n@mark(PosX, \"x\"),mark(PosY, \"y\")\n", v18: "```go\nfield x int\n```\n\n\\@mark\\(PosX, \\\"x\\\"\\),mark\\(PosY, \\\"y\\\"\\)"}, + {v19: "```go\nfield x int\n```\n\nX coord\n", v18: "```go\nfield x int\n```\n\nX coord"}, + {v19: "```go\nfield x string\n```\n\nX value field\n", v18: "```go\nfield x string\n```\n\nX value field"}, + {v19: "```go\nfield y int\n```\n\nY coord\n", v18: "```go\nfield y int\n```\n\nY coord"}, + {v19: "```go\nfunc (*sync.Mutex).Lock()\n```\n\nLock locks m.\n\n\n[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock)", v18: "```go\nfunc (*sync.Mutex).Lock()\n```\n\nLock locks m\\.\n\n[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock)"}, + {v19: "```go\nfunc (*types.object).Name() string\n```\n\nName returns the object's (package-local, unqualified) name.\n\n\n[`(types.TypeName).Name` on pkg.go.dev](https://pkg.go.dev/go/types#TypeName.Name)", v18: "```go\nfunc (*types.object).Name() string\n```\n\nName returns the object\\'s \\(package\\-local, unqualified\\) name\\.\n\n[`(types.TypeName).Name` on pkg.go.dev](https://pkg.go.dev/go/types#TypeName.Name)"}, + {v19: "```go\nfunc (a.H).Goodbye()\n```\n\n@mark(AGoodbye, \"Goodbye\")\n\n\n[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#H.Goodbye)", v18: "```go\nfunc (a.H).Goodbye()\n```\n\n\\@mark\\(AGoodbye, \\\"Goodbye\\\"\\)\n\n[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#H.Goodbye)"}, + {v19: "```go\nfunc (a.I).B()\n```\n\n@mark(AB, \"B\")\n\n\n[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#I.B)", v18: "```go\nfunc (a.I).B()\n```\n\n\\@mark\\(AB, \\\"B\\\"\\)\n\n[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#I.B)"}, + {v19: "```go\nfunc (a.J).Hello()\n```\n\n@mark(AHello, \"Hello\")\n\n\n[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#J.Hello)", v18: "```go\nfunc (a.J).Hello()\n```\n\n\\@mark\\(AHello, \\\"Hello\\\"\\)\n\n[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#J.Hello)"}, + {v19: "```go\nfunc (interface).open() error\n```\n\nopen method comment\n", v18: "```go\nfunc (interface).open() error\n```\n\nopen method comment"}, + {v19: "```go\nfunc make(t Type, size ...int) Type\n```\n\nThe make built-in function allocates and initializes an object of type slice, map, or chan (only).\n\n\n[`make` on pkg.go.dev](https://pkg.go.dev/builtin#make)", v18: "```go\nfunc make(t Type, size ...int) Type\n```\n\nThe make built\\-in function allocates and initializes an object of type slice, map, or chan \\(only\\)\\.\n\n[`make` on pkg.go.dev](https://pkg.go.dev/builtin#make)"}, + {v19: "```go\ntype A string\n```\n\n@mark(AString, \"A\")\n\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)", v18: "```go\ntype A string\n```\n\n\\@mark\\(AString, \\\"A\\\"\\)\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)"}, + {v19: "```go\ntype a struct {\n\tx string\n}\n```\n\n1st type declaration block\n", v18: "```go\ntype a struct {\n\tx string\n}\n```\n\n1st type declaration block"}, + {v19: "```go\ntype aAlias = a.A\n```\n\n@mark(aAlias, \"aAlias\")\n", v18: "```go\ntype aAlias = a.A\n```\n\n\\@mark\\(aAlias, \\\"aAlias\\\"\\)"}, + {v19: "```go\ntype b struct{}\n```\n\nb has a comment\n", v18: "```go\ntype b struct{}\n```\n\nb has a comment"}, + {v19: "```go\ntype c struct {\n\tf string\n}\n```\n\nc is a struct\n", v18: "```go\ntype c struct {\n\tf string\n}\n```\n\nc is a struct"}, + {v19: "```go\ntype d string\n```\n\n3rd type declaration block\n", v18: "```go\ntype d string\n```\n\n3rd type declaration block"}, + {v19: "```go\ntype e struct {\n\tf float64\n}\n```\n\ne has a comment\n", v18: "```go\ntype e struct {\n\tf float64\n}\n```\n\ne has a comment"}, + {v19: "```go\ntype string string\n```\n\nstring is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8-encoded text.\n\n\n[`string` on pkg.go.dev](https://pkg.go.dev/builtin#string)", v18: "```go\ntype string string\n```\n\nstring is the set of all strings of 8\\-bit bytes, conventionally but not necessarily representing UTF\\-8\\-encoded text\\.\n\n[`string` on pkg.go.dev](https://pkg.go.dev/builtin#string)"}, + {v19: "```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)", v18: "```go\nvar Other Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"}, + {v19: "```go\nvar _ A\n```\n\nvariable of type a.A\n", v18: "```go\nvar _ A\n```\n\nvariable of type a\\.A"}, + {v19: "```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)", v18: "```go\nvar a.Other a.Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"}, + {v19: "```go\nvar err error\n```\n\n@err\n", v18: "```go\nvar err error\n```\n\n\\@err"}, + {v19: "```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf\n", v18: "```go\nvar myUnclosedIf string\n```\n\n\\@myUnclosedIf"}, + {v19: "```go\nvar x string\n```\n\nx is a variable.\n", v18: "```go\nvar x string\n```\n\nx is a variable\\."}, + {v19: "```go\nvar z string\n```\n\nz is a variable too.\n", v18: "```go\nvar z string\n```\n\nz is a variable too\\."}, + {v19: "godef/a/a.go:26:6-7: defined here as ```go\ntype A string\n```\n\n@mark(AString, \"A\")\n\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)", v18: "godef/a/a.go:26:6-7: defined here as ```go\ntype A string\n```\n\n\\@mark\\(AString, \\\"A\\\"\\)\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)"}, + {v19: "godef/a/a.go:33:6-9: defined here as ```go\nvar err error\n```\n\n@err", v18: "godef/a/a.go:33:6-9: defined here as ```go\nvar err error\n```\n\n\\@err"}, + {v19: "godef/a/d.go:6:2-8: defined here as ```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)", v18: "godef/a/d.go:6:2-8: defined here as ```go\nfield Member string\n```\n\n\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)"}, + {v19: "godef/a/d.go:9:5-10: defined here as ```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)", v18: "godef/a/d.go:9:5-10: defined here as ```go\nvar Other Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"}, + {v19: "godef/a/d.go:9:5-10: defined here as ```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)", v18: "godef/a/d.go:9:5-10: defined here as ```go\nvar a.Other a.Thing\n```\n\n\\@Other\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"}, + {v19: "godef/a/random.go:13:2-3: defined here as ```go\nfield x int\n```\n\n@mark(PosX, \"x\"),mark(PosY, \"y\")", v18: "godef/a/random.go:13:2-3: defined here as ```go\nfield x int\n```\n\n\\@mark\\(PosX, \\\"x\\\"\\),mark\\(PosY, \\\"y\\\"\\)"}, + {v19: "godef/b/b.go:25:6-12: defined here as ```go\ntype aAlias = a.A\n```\n\n@mark(aAlias, \"aAlias\")", v18: "godef/b/b.go:25:6-12: defined here as ```go\ntype aAlias = a.A\n```\n\n\\@mark\\(aAlias, \\\"aAlias\\\"\\)"}, + {v19: "godef/b/b.go:28:2-4: defined here as ```go\nfield F1 int\n```\n\n@mark(S1F1, \"F1\")\n\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)", v18: "godef/b/b.go:28:2-4: defined here as ```go\nfield F1 int\n```\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)"}, + {v19: "godef/b/b.go:29:2-4: defined here as ```go\nfield S2 S2\n```\n\n@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)", v18: "godef/b/b.go:29:2-4: defined here as ```go\nfield S2 S2\n```\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)"}, + {v19: "godef/b/b.go:35:2-4: defined here as ```go\nfield F1 string\n```\n\n@mark(S2F1, \"F1\")\n\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)", v18: "godef/b/b.go:35:2-4: defined here as ```go\nfield F1 string\n```\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)"}, + {v19: "godef/b/b.go:36:2-4: defined here as ```go\nfield F2 int\n```\n\n@mark(S2F2, \"F2\")\n\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)", v18: "godef/b/b.go:36:2-4: defined here as ```go\nfield F2 int\n```\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)"}, + {v19: "godef/b/b.go:57:7-8: defined here as ```go\nconst X untyped int = 0\n```\n\n@mark(bX, \"X\"),godef(\"X\", bX)\n\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)", v18: "godef/b/b.go:57:7-8: defined here as ```go\nconst X untyped int = 0\n```\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)"}, + {v19: "godef/broken/unclosedIf.go:7:7-19: defined here as ```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf", v18: "godef/broken/unclosedIf.go:7:7-19: defined here as ```go\nvar myUnclosedIf string\n```\n\n\\@myUnclosedIf"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/a.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 26,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 467\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 26,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 468\n\t\t}\n\t},\n\t\"description\": \"```go\\ntype A string\\n```\\n\\n@mark(AString, \\\"A\\\")\\n\\n\\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/a.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 26,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 467\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 26,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 468\n\t\t}\n\t},\n\t\"description\": \"```go\\ntype A string\\n```\\n\\n\\\\@mark\\\\(AString, \\\\\\\"A\\\\\\\"\\\\)\\n\\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/a.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 33,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 612\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 33,\n\t\t\t\"column\": 9,\n\t\t\t\"offset\": 615\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar err error\\n```\\n\\n@err\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/a.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 33,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 612\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 33,\n\t\t\t\"column\": 9,\n\t\t\t\"offset\": 615\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar err error\\n```\\n\\n\\\\@err\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 6,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 90\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 6,\n\t\t\t\"column\": 8,\n\t\t\t\"offset\": 96\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield Member string\\n```\\n\\n@Member\\n\\n\\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 6,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 90\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 6,\n\t\t\t\"column\": 8,\n\t\t\t\"offset\": 96\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield Member string\\n```\\n\\n\\\\@Member\\n\\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 5,\n\t\t\t\"offset\": 121\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 10,\n\t\t\t\"offset\": 126\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar Other Thing\\n```\\n\\n@Other\\n\\n\\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 5,\n\t\t\t\"offset\": 121\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 10,\n\t\t\t\"offset\": 126\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar Other Thing\\n```\\n\\n\\\\@Other\\n\\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 5,\n\t\t\t\"offset\": 121\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 10,\n\t\t\t\"offset\": 126\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar a.Other a.Thing\\n```\\n\\n@Other\\n\\n\\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/d.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 5,\n\t\t\t\"offset\": 121\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 9,\n\t\t\t\"column\": 10,\n\t\t\t\"offset\": 126\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar a.Other a.Thing\\n```\\n\\n\\\\@Other\\n\\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/random.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 13,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 187\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 13,\n\t\t\t\"column\": 3,\n\t\t\t\"offset\": 188\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield x int\\n```\\n\\n@mark(PosX, \\\"x\\\"),mark(PosY, \\\"y\\\")\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/a/random.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 13,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 187\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 13,\n\t\t\t\"column\": 3,\n\t\t\t\"offset\": 188\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield x int\\n```\\n\\n\\\\@mark\\\\(PosX, \\\\\\\"x\\\\\\\"\\\\),mark\\\\(PosY, \\\\\\\"y\\\\\\\"\\\\)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 25,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 542\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 25,\n\t\t\t\"column\": 12,\n\t\t\t\"offset\": 548\n\t\t}\n\t},\n\t\"description\": \"```go\\ntype aAlias = a.A\\n```\\n\\n@mark(aAlias, \\\"aAlias\\\")\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 25,\n\t\t\t\"column\": 6,\n\t\t\t\"offset\": 542\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 25,\n\t\t\t\"column\": 12,\n\t\t\t\"offset\": 548\n\t\t}\n\t},\n\t\"description\": \"```go\\ntype aAlias = a.A\\n```\\n\\n\\\\@mark\\\\(aAlias, \\\\\\\"aAlias\\\\\\\"\\\\)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 28,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 606\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 28,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 608\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F1 int\\n```\\n\\n@mark(S1F1, \\\"F1\\\")\\n\\n\\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 28,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 606\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 28,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 608\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F1 int\\n```\\n\\n\\\\@mark\\\\(S1F1, \\\\\\\"F1\\\\\\\"\\\\)\\n\\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 29,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 638\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 29,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 640\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield S2 S2\\n```\\n\\n@godef(\\\"S2\\\", S2),mark(S1S2, \\\"S2\\\")\\n\\n\\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 29,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 638\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 29,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 640\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield S2 S2\\n```\\n\\n\\\\@godef\\\\(\\\\\\\"S2\\\\\\\", S2\\\\),mark\\\\(S1S2, \\\\\\\"S2\\\\\\\"\\\\)\\n\\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 35,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 781\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 35,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 783\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F1 string\\n```\\n\\n@mark(S2F1, \\\"F1\\\")\\n\\n\\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 35,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 781\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 35,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 783\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F1 string\\n```\\n\\n\\\\@mark\\\\(S2F1, \\\\\\\"F1\\\\\\\"\\\\)\\n\\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 36,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 814\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 36,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 816\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F2 int\\n```\\n\\n@mark(S2F2, \\\"F2\\\")\\n\\n\\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 36,\n\t\t\t\"column\": 2,\n\t\t\t\"offset\": 814\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 36,\n\t\t\t\"column\": 4,\n\t\t\t\"offset\": 816\n\t\t}\n\t},\n\t\"description\": \"```go\\nfield F2 int\\n```\\n\\n\\\\@mark\\\\(S2F2, \\\\\\\"F2\\\\\\\"\\\\)\\n\\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 57,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 1249\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 57,\n\t\t\t\"column\": 8,\n\t\t\t\"offset\": 1250\n\t\t}\n\t},\n\t\"description\": \"```go\\nconst X untyped int = 0\\n```\\n\\n@mark(bX, \\\"X\\\"),godef(\\\"X\\\", bX)\\n\\n\\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/b/b.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 57,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 1249\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 57,\n\t\t\t\"column\": 8,\n\t\t\t\"offset\": 1250\n\t\t}\n\t},\n\t\"description\": \"```go\\nconst X untyped int = 0\\n```\\n\\n\\\\@mark\\\\(bX, \\\\\\\"X\\\\\\\"\\\\),godef\\\\(\\\\\\\"X\\\\\\\", bX\\\\)\\n\\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)\"\n}\n"}, + {v19: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/broken/unclosedIf.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 7,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 68\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 7,\n\t\t\t\"column\": 19,\n\t\t\t\"offset\": 80\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar myUnclosedIf string\\n```\\n\\n@myUnclosedIf\"\n}", v18: "{\n\t\"span\": {\n\t\t\"uri\": \"file://godef/broken/unclosedIf.go\",\n\t\t\"start\": {\n\t\t\t\"line\": 7,\n\t\t\t\"column\": 7,\n\t\t\t\"offset\": 68\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": 7,\n\t\t\t\"column\": 19,\n\t\t\t\"offset\": 80\n\t\t}\n\t},\n\t\"description\": \"```go\\nvar myUnclosedIf string\\n```\\n\\n\\\\@myUnclosedIf\"\n}\n"}, +} diff --git a/internal/lsp/tests/metadata_go119.go b/internal/lsp/tests/metadata_go119.go new file mode 100644 index 0000000000..462f130662 --- /dev/null +++ b/internal/lsp/tests/metadata_go119.go @@ -0,0 +1,23 @@ +// 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 tests + +import ( + "testing" +) + +// The markdown in the golden files matches the converter in comment.go, +// but for go1.19 and later the conversion is done using go/doc/comment. +// Compared to the newer version, the older version +// has extra escapes, and treats code blocks slightly differently. +func CheckSameMarkdown(t *testing.T, got, want string) { + t.Helper() + if got != want { + t.Errorf("got %q, want %q", got, want) + } +}