diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go index e19dda18af..d8ba9a0d40 100644 --- a/internal/lsp/source/hover.go +++ b/internal/lsp/source/hover.go @@ -98,11 +98,13 @@ func HoverIdentifier(ctx context.Context, i *IdentifierInfo) (*HoverInformation, case types.Object: // If the variable is implicitly declared in a type switch, we need to // manually generate its object string. - if v, ok := x.(*types.Var); ok && i.Declaration.typeSwitchImplicit { - h.Signature = fmt.Sprintf("var %s %s", v.Name(), types.TypeString(i.enclosing, i.qf)) - } else { - h.Signature = objectString(x, i.qf) + if typ := i.Declaration.typeSwitchImplicit; typ != nil { + if v, ok := x.(*types.Var); ok { + h.Signature = fmt.Sprintf("var %s %s", v.Name(), types.TypeString(typ, i.qf)) + break + } } + h.Signature = objectString(x, i.qf) } if obj := i.Declaration.obj; obj != nil { h.SingleLine = objectString(obj, i.qf) @@ -143,12 +145,11 @@ func pathLinkAndSymbolName(i *IdentifierInfo) (string, string, string) { var rTypeName string switch obj := obj.(type) { case *types.Var: + // If the object is a field, and we have an associated selector + // composite literal, or struct, we can determine the link. if obj.IsField() { - // If the object is a field, and we have an associated selector - // composite literal, or struct, we can determine the link. - switch typ := i.enclosing.(type) { - case *types.Named: - rTypeName = typ.Obj().Name() + if named, ok := i.enclosing.(*types.Named); ok { + rTypeName = named.Obj().Name() } } case *types.Func: @@ -161,10 +162,15 @@ func pathLinkAndSymbolName(i *IdentifierInfo) (string, string, string) { case *types.Struct: rTypeName = r.Name() case *types.Named: - if named, ok := i.enclosing.(*types.Named); ok { - rTypeName = named.Obj().Name() - } else if !rtyp.Obj().Exported() { - return "", "", "" + // If we have an unexported type, see if the enclosing type is + // exported (we may have an interface or struct we can link + // to). If not, don't show any link. + if !rtyp.Obj().Exported() { + if named := i.enclosing.(*types.Named); ok && named.Obj().Exported() { + rTypeName = named.Obj().Name() + } else { + return "", "", "" + } } else { rTypeName = rtyp.Obj().Name() } diff --git a/internal/lsp/source/identifier.go b/internal/lsp/source/identifier.go index 25ea2d0b25..5b7e43ac54 100644 --- a/internal/lsp/source/identifier.go +++ b/internal/lsp/source/identifier.go @@ -32,7 +32,8 @@ type IdentifierInfo struct { ident *ast.Ident - // enclosing is an expression used to determine the link anchor for an identifier. + // enclosing is an expression used to determine the link anchor for an + // identifier. If it's a named type, it should be exported. enclosing types.Type pkg Package @@ -45,8 +46,9 @@ type Declaration struct { obj types.Object // typeSwitchImplicit indicates that the declaration is in an implicit - // type switch. - typeSwitchImplicit bool + // type switch. Its type is the type of the variable on the right-hand + // side of the type switch. + typeSwitchImplicit types.Type } // Identifier returns identifier information for a position @@ -158,13 +160,13 @@ func findIdentifier(ctx context.Context, s Snapshot, pkg Package, file *ast.File if result.Declaration.obj == nil { // If there was no types.Object for the declaration, there might be an // implicit local variable declaration in a type switch. - if objs := typeSwitchImplicits(pkg, path); len(objs) > 0 { - result.Declaration.typeSwitchImplicit = true + if objs, typ := typeSwitchImplicits(pkg, path); len(objs) > 0 { // There is no types.Object for the declaration of an implicit local variable, // but all of the types.Objects associated with the usages of this variable can be // used to connect it back to the declaration. // Preserve the first of these objects and treat it as if it were the declaring object. result.Declaration.obj = objs[0] + result.Declaration.typeSwitchImplicit = typ } else { // Probably a type error. return nil, errors.Errorf("no object for ident %v", result.Name) @@ -236,8 +238,25 @@ func searchForEnclosing(pkg Package, path []ast.Node) types.Type { for _, n := range path { switch n := n.(type) { case *ast.SelectorExpr: - if selection, ok := pkg.GetTypesInfo().Selections[n]; ok { - return deref(selection.Recv()) + if sel, ok := pkg.GetTypesInfo().Selections[n]; ok { + recv := deref(sel.Recv()) + + // Keep track of the last exported type seen. + var exported *types.Named + if named, ok := recv.(*types.Named); ok && named.Obj().Exported() { + exported = named + } + // We don't want the last element, as that's the field or + // method itself. + for _, index := range sel.Index()[:len(sel.Index())-1] { + if r, ok := recv.Underlying().(*types.Struct); ok { + recv = deref(r.Field(index).Type()) + if named, ok := recv.(*types.Named); ok && named.Obj().Exported() { + exported = named + } + } + } + return exported } case *ast.CompositeLit: if t, ok := pkg.GetTypesInfo().Types[n]; ok { @@ -249,15 +268,6 @@ func searchForEnclosing(pkg Package, path []ast.Node) types.Type { return t.Type() } } - case *ast.TypeSwitchStmt: - // The right-hand side of a type switch should only have one - // element, and we need to track its type in order to generate - // hover information for implicit type switch variables. - if assign, ok := n.Assign.(*ast.AssignStmt); ok && len(assign.Rhs) == 1 { - if rhs := assign.Rhs[0].(*ast.TypeAssertExpr); ok { - return pkg.GetTypesInfo().TypeOf(rhs.X) - } - } } } return nil @@ -339,12 +349,13 @@ func importSpec(s Snapshot, pkg Package, file *ast.File, pos token.Pos) (*Identi return result, nil } -// typeSwitchImplicits returns all the implicit type switch objects -// that correspond to the leaf *ast.Ident. -func typeSwitchImplicits(pkg Package, path []ast.Node) []types.Object { +// typeSwitchImplicits returns all the implicit type switch objects that +// correspond to the leaf *ast.Ident. It also returns the original type +// associated with the identifier (outside of a case clause). +func typeSwitchImplicits(pkg Package, path []ast.Node) ([]types.Object, types.Type) { ident, _ := path[0].(*ast.Ident) if ident == nil { - return nil + return nil, nil } var ( @@ -376,7 +387,6 @@ Outer: case *ast.TypeSwitchStmt: // Look for the type switch that owns our previously found // *ast.AssignStmt or *ast.CaseClause. - if n.Assign == assign { ts = n break Outer @@ -390,11 +400,9 @@ Outer: } } } - if ts == nil { - return nil + return nil, nil } - // Our leaf ident refers to a type switch variable. Fan out to the // type switch's implicit case clause objects. var objs []types.Object @@ -403,5 +411,14 @@ Outer: objs = append(objs, ccObj) } } - return objs + // The right-hand side of a type switch should only have one + // element, and we need to track its type in order to generate + // hover information for implicit type switch variables. + var typ types.Type + if assign, ok := ts.Assign.(*ast.AssignStmt); ok && len(assign.Rhs) == 1 { + if rhs := assign.Rhs[0].(*ast.TypeAssertExpr); ok { + typ = pkg.GetTypesInfo().TypeOf(rhs.X) + } + } + return objs, typ } diff --git a/internal/lsp/source/implementation.go b/internal/lsp/source/implementation.go index 527c8e68d8..3bf876b925 100644 --- a/internal/lsp/source/implementation.go +++ b/internal/lsp/source/implementation.go @@ -230,7 +230,7 @@ func qualifiedObjsAtProtocolPos(ctx context.Context, s Snapshot, fh FileHandle, // If leaf represents an implicit type switch object or the type // switch "assign" variable, expand to all of the type switch's // implicit objects. - if implicits := typeSwitchImplicits(searchpkg, path); len(implicits) > 0 { + if implicits, _ := typeSwitchImplicits(searchpkg, path); len(implicits) > 0 { objs = append(objs, implicits...) } else { obj := searchpkg.GetTypesInfo().ObjectOf(leaf) diff --git a/internal/lsp/testdata/lsp/primarymod/godef/a/a.go b/internal/lsp/testdata/lsp/primarymod/godef/a/a.go index f818acc822..b157a71126 100644 --- a/internal/lsp/testdata/lsp/primarymod/godef/a/a.go +++ b/internal/lsp/testdata/lsp/primarymod/godef/a/a.go @@ -42,3 +42,33 @@ func AStuff() { //@AStuff var typ *types.Named //@mark(typesImport, "types"),hover("types", typesImport) typ.Obj().Name() //@Name,hover("Name", Name) } + +type A struct { +} + +func (_ A) Hi() {} //@mark(AHi, "Hi") + +type S struct { + Field int //@mark(AField, "Field") + R // embed a struct + H // embed an interface +} + +type R struct { + Field2 int //@mark(AField2, "Field2") +} + +func (_ R) Hey() {} //@mark(AHey, "Hey") + +type H interface { + Goodbye() //@mark(AGoodbye, "Goodbye") +} + +type I interface { + B() //@mark(AB, "B") + J +} + +type J interface { + Hello() //@mark(AHello, "Hello") +} diff --git a/internal/lsp/testdata/lsp/primarymod/godef/b/b.go b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go index ca6c957d58..a510a4543d 100644 --- a/internal/lsp/testdata/lsp/primarymod/godef/b/b.go +++ b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go @@ -5,9 +5,26 @@ import ( "golang.org/x/tools/internal/lsp/godef/a" //@mark(AImport, re"\".*\"") ) +type Embed struct { + *a.A + a.I + a.S +} + +func _() { + e := Embed{} + e.Hi() //@hover("Hi", AHi) + e.B() //@hover("B", AB) + e.Field //@hover("Field", AField) + e.Field2 //@hover("Field2", AField2) + e.Hello() //@hover("Hello", AHello) + e.Hey() //@hover("Hey", AHey) + e.Goodbye() //@hover("Goodbye", AGoodbye) +} + type S1 struct { //@S1 F1 int //@mark(S1F1, "F1") - S2 //@godef("S2", S2), mark(S1S2, "S2") + S2 //@godef("S2", S2),mark(S1S2, "S2") a.A //@godef("A", AString) } diff --git a/internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden index 47208e985a..e2ff0bb587 100644 --- a/internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden +++ b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden @@ -1,3 +1,55 @@ +-- AB-hover -- +```go +func (a.I).B() +``` + +[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#I.B) + +\@mark\(AB, \"B\"\) +-- AField-hover -- +```go +field Field int +``` + +[`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#S.Field) + +\@mark\(AField, \"Field\"\) +-- AField2-hover -- +```go +field Field2 int +``` + +[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#R.Field2) + +\@mark\(AField2, \"Field2\"\) +-- AGoodbye-hover -- +```go +func (a.H).Goodbye() +``` + +[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#H.Goodbye) + +\@mark\(AGoodbye, \"Goodbye\"\) +-- AHello-hover -- +```go +func (a.J).Hello() +``` + +[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#J.Hello) + +\@mark\(AHello, \"Hello\"\) +-- AHey-hover -- +```go +func (a.R).Hey() +``` + +[`(a.R).Hey` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#R.Hey) +-- AHi-hover -- +```go +func (a.A).Hi() +``` + +[`(a.A).Hi` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A.Hi) -- AImport-definition -- godef/b/b.go:5:2-43: defined here as ```go package a ("golang.org/x/tools/internal/lsp/godef/a") @@ -91,10 +143,10 @@ func a.AStuff() [`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff) -- S1-definition -- -godef/b/b.go:8:6-8: defined here as ```go +godef/b/b.go:25:6-8: defined here as ```go S1 struct { F1 int //@mark(S1F1, "F1") - S2 //@godef("S2", S2), mark(S1S2, "S2") + S2 //@godef("S2", S2),mark(S1S2, "S2") a.A //@godef("A", AString) } ``` @@ -105,31 +157,31 @@ S1 struct { "span": { "uri": "file://godef/b/b.go", "start": { - "line": 8, + "line": 25, "column": 6, - "offset": 193 + "offset": 521 }, "end": { - "line": 8, + "line": 25, "column": 8, - "offset": 195 + "offset": 523 } }, - "description": "```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)" + "description": "```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)" } -- S1-hover -- ```go S1 struct { F1 int //@mark(S1F1, "F1") - S2 //@godef("S2", S2), mark(S1S2, "S2") + S2 //@godef("S2", S2),mark(S1S2, "S2") a.A //@godef("A", AString) } ``` [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1) -- S1F1-definition -- -godef/b/b.go:9:2-4: defined here as ```go +godef/b/b.go:26:2-4: defined here as ```go field F1 int ``` @@ -141,14 +193,14 @@ field F1 int "span": { "uri": "file://godef/b/b.go", "start": { - "line": 9, + "line": 26, "column": 2, - "offset": 212 + "offset": 540 }, "end": { - "line": 9, + "line": 26, "column": 4, - "offset": 214 + "offset": 542 } }, "description": "```go\nfield F1 int\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\n\\@mark\\(S1F1, \\\"F1\\\"\\)" @@ -163,29 +215,29 @@ field F1 int \@mark\(S1F1, \"F1\"\) -- S1S2-definition -- -godef/b/b.go:10:2-4: defined here as ```go +godef/b/b.go:27:2-4: defined here as ```go field S2 S2 ``` [`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2) -\@godef\(\"S2\", S2\), mark\(S1S2, \"S2\"\) +\@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\) -- S1S2-definition-json -- { "span": { "uri": "file://godef/b/b.go", "start": { - "line": 10, + "line": 27, "column": 2, - "offset": 241 + "offset": 569 }, "end": { - "line": 10, + "line": 27, "column": 4, - "offset": 243 + "offset": 571 } }, - "description": "```go\nfield S2 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\n\\@godef\\(\\\"S2\\\", S2\\), mark\\(S1S2, \\\"S2\\\"\\)" + "description": "```go\nfield S2 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\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)" } -- S1S2-hover -- @@ -195,9 +247,9 @@ field S2 S2 [`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2) -\@godef\(\"S2\", S2\), mark\(S1S2, \"S2\"\) +\@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\) -- S2-definition -- -godef/b/b.go:14:6-8: defined here as ```go +godef/b/b.go:31:6-8: defined here as ```go S2 struct { F1 string //@mark(S2F1, "F1") F2 int //@mark(S2F2, "F2") @@ -211,14 +263,14 @@ S2 struct { "span": { "uri": "file://godef/b/b.go", "start": { - "line": 14, + "line": 31, "column": 6, - "offset": 326 + "offset": 653 }, "end": { - "line": 14, + "line": 31, "column": 8, - "offset": 328 + "offset": 655 } }, "description": "```go\nS2 struct {\n\tF1 string //@mark(S2F1, \"F1\")\n\tF2 int //@mark(S2F2, \"F2\")\n\t*a.A //@godef(\"A\", AString),godef(\"a\",AImport)\n}\n```\n\n[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)" @@ -235,7 +287,7 @@ S2 struct { [`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2) -- S2F1-definition -- -godef/b/b.go:15:2-4: defined here as ```go +godef/b/b.go:32:2-4: defined here as ```go field F1 string ``` @@ -247,14 +299,14 @@ field F1 string "span": { "uri": "file://godef/b/b.go", "start": { - "line": 15, + "line": 32, "column": 2, - "offset": 345 + "offset": 672 }, "end": { - "line": 15, + "line": 32, "column": 4, - "offset": 347 + "offset": 674 } }, "description": "```go\nfield F1 string\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\n\\@mark\\(S2F1, \\\"F1\\\"\\)" @@ -269,11 +321,11 @@ field F1 string \@mark\(S2F1, \"F1\"\) -- S2F2-definition -- -godef/b/b.go:16:2-4: defined here as ```go +godef/b/b.go:33:2-4: defined here as ```go field F2 int ``` -[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2) +[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2) \@mark\(S2F2, \"F2\"\) -- S2F2-definition-json -- @@ -281,17 +333,17 @@ field F2 int "span": { "uri": "file://godef/b/b.go", "start": { - "line": 16, + "line": 33, "column": 2, - "offset": 378 + "offset": 705 }, "end": { - "line": 16, + "line": 33, "column": 4, - "offset": 380 + "offset": 707 } }, - "description": "```go\nfield F2 int\n```\n\n[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2)\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)" + "description": "```go\nfield F2 int\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\n\\@mark\\(S2F2, \\\"F2\\\"\\)" } -- S2F2-hover -- @@ -299,11 +351,11 @@ field F2 int field F2 int ``` -[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2) +[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F2) \@mark\(S2F2, \"F2\"\) -- bX-definition -- -godef/b/b.go:37:7-8: defined here as ```go +godef/b/b.go:54:7-8: defined here as ```go const X untyped int = 0 ``` @@ -315,14 +367,14 @@ const X untyped int = 0 "span": { "uri": "file://godef/b/b.go", "start": { - "line": 37, + "line": 54, "column": 7, - "offset": 813 + "offset": 1140 }, "end": { - "line": 37, + "line": 54, "column": 8, - "offset": 814 + "offset": 1141 } }, "description": "```go\nconst X untyped int = 0\n```\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)" diff --git a/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden index fdf2216f34..85c6854f61 100644 --- a/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden +++ b/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden @@ -1,8 +1,8 @@ -- S1-definition -- -godef/b/b.go:8:6-8: defined here as ```go +godef/b/b.go:25:6-8: defined here as ```go S1 struct { F1 int //@mark(S1F1, "F1") - S2 //@godef("S2", S2), mark(S1S2, "S2") + S2 //@godef("S2", S2),mark(S1S2, "S2") a.A //@godef("A", AString) } ``` @@ -13,31 +13,31 @@ S1 struct { "span": { "uri": "file://godef/b/b.go", "start": { - "line": 8, + "line": 25, "column": 6, - "offset": 193 + "offset": 521 }, "end": { - "line": 8, + "line": 25, "column": 8, - "offset": 195 + "offset": 523 } }, - "description": "```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)" + "description": "```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)" } -- S1-hover -- ```go S1 struct { F1 int //@mark(S1F1, "F1") - S2 //@godef("S2", S2), mark(S1S2, "S2") + S2 //@godef("S2", S2),mark(S1S2, "S2") a.A //@godef("A", AString) } ``` [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1) -- S1F1-definition -- -godef/b/b.go:9:2-4: defined here as ```go +godef/b/b.go:26:2-4: defined here as ```go field F1 int ``` @@ -49,14 +49,14 @@ field F1 int "span": { "uri": "file://godef/b/b.go", "start": { - "line": 9, + "line": 26, "column": 2, - "offset": 212 + "offset": 540 }, "end": { - "line": 9, + "line": 26, "column": 4, - "offset": 214 + "offset": 542 } }, "description": "```go\nfield F1 int\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\n\\@mark\\(S1F1, \\\"F1\\\"\\)" diff --git a/internal/lsp/testdata/lsp/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden index 4c64565ffc..205b45d584 100644 --- a/internal/lsp/testdata/lsp/summary.txt.golden +++ b/internal/lsp/testdata/lsp/summary.txt.golden @@ -13,7 +13,7 @@ FormatCount = 6 ImportCount = 8 SuggestedFixCount = 31 FunctionExtractionCount = 5 -DefinitionsCount = 56 +DefinitionsCount = 63 TypeDefinitionsCount = 2 HighlightsCount = 69 ReferencesCount = 11