| This test was ported from 'godef' in the old marker tests. | |
| It tests various hover and definition requests. | |
| -- go.mod -- | |
| module godef.test | |
| go 1.18 | |
| -- a/a_x_test.go -- | |
| package a_test | |
| import ( | |
| "testing" | |
| ) | |
| func TestA2(t *testing.T) { //@hover("TestA2", "TestA2", TestA2) | |
| Nonexistant() //@diag("Nonexistant", re"(undeclared name|undefined): Nonexistant") | |
| } | |
| -- @TestA2 -- | |
| ```go | |
| func TestA2(t *testing.T) | |
| ``` | |
| -- @ember -- | |
| ```go | |
| field Member string | |
| ``` | |
| --- | |
| @loc(Member, "Member") | |
| --- | |
| [`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing.Member) | |
| -- a/d.go -- | |
| package a //@hover("a", _, a) | |
| import "fmt" | |
| type Thing struct { //@loc(Thing, "Thing") | |
| Member string //@loc(Member, "Member") | |
| } | |
| var Other Thing //@loc(Other, "Other") | |
| func Things(val []string) []Thing { //@loc(Things, "Things") | |
| return nil | |
| } | |
| func (t Thing) Method(i int) string { //@loc(Method, "Method") | |
| return t.Member | |
| } | |
| func (t Thing) Method3() { | |
| } | |
| func (t *Thing) Method2(i int, j int) (error, string) { | |
| return nil, t.Member | |
| } | |
| func (t *Thing) private() { | |
| } | |
| func useThings() { | |
| t := Thing{ //@hover("ing", "Thing", ing) | |
| Member: "string", //@hover("ember", "Member", ember), def("ember", Member) | |
| } | |
| fmt.Print(t.Member) //@hover("ember", "Member", ember), def("ember", Member) | |
| fmt.Print(Other) //@hover("ther", "Other", ther), def("ther", Other) | |
| Things(nil) //@hover("ings", "Things", ings), def("ings", Things) | |
| t.Method(0) //@hover("eth", "Method", eth), def("eth", Method) | |
| } | |
| type NextThing struct { //@loc(NextThing, "NextThing") | |
| Thing | |
| Value int | |
| } | |
| func (n NextThing) another() string { | |
| return n.Member | |
| } | |
| // Shadows Thing.Method3 | |
| func (n *NextThing) Method3() int { | |
| return n.Value | |
| } | |
| var nextThing NextThing //@hover("NextThing", "NextThing", NextThing), def("NextThing", NextThing) | |
| -- @ings -- | |
| ```go | |
| func Things(val []string) []Thing | |
| ``` | |
| --- | |
| [`a.Things` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Things) | |
| -- @ther -- | |
| ```go | |
| var Other Thing | |
| ``` | |
| --- | |
| @loc(Other, "Other") | |
| --- | |
| [`a.Other` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Other) | |
| -- @a -- | |
| -- @ing -- | |
| ```go | |
| type Thing struct { | |
| Member string //@loc(Member, "Member") | |
| } | |
| ``` | |
| --- | |
| ```go | |
| func (t Thing) Method(i int) string | |
| func (t *Thing) Method2(i int, j int) (error, string) | |
| func (t Thing) Method3() | |
| func (t *Thing) private() | |
| ``` | |
| --- | |
| [`a.Thing` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing) | |
| -- @NextThing -- | |
| ```go | |
| type NextThing struct { | |
| Thing | |
| Value int | |
| } | |
| ``` | |
| --- | |
| ```go | |
| // Embedded fields: | |
| Member string // through Thing | |
| ``` | |
| ```go | |
| func (t Thing) Method(i int) string | |
| func (t *Thing) Method2(i int, j int) (error, string) | |
| func (n *NextThing) Method3() int | |
| func (n NextThing) another() string | |
| func (t *Thing) private() | |
| ``` | |
| --- | |
| [`a.NextThing` on pkg.go.dev](https://pkg.go.dev/godef.test/a#NextThing) | |
| -- @eth -- | |
| ```go | |
| func (t Thing) Method(i int) string | |
| ``` | |
| --- | |
| [`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing.Method) | |
| -- a/f.go -- | |
| // Package a is a package for testing go to definition. | |
| package a | |
| import "fmt" | |
| func TypeStuff() { | |
| var x string | |
| switch y := any(x).(type) { //@loc(y, "y"), hover("y", "y", y) , def("y", y) | |
| case int: //@loc(intY, "int") | |
| fmt.Printf("%v", y) //@hover("y", "y", inty), def("y", y) | |
| case string: //@loc(stringY, "string") | |
| fmt.Printf("%v", y) //@hover("y", "y", stringy), def("y", y) | |
| } | |
| } | |
| -- @inty -- | |
| ```go | |
| var y int | |
| ``` | |
| -- @stringy -- | |
| ```go | |
| var y string | |
| ``` | |
| -- @y -- | |
| ```go | |
| var y any | |
| ``` | |
| -- a/h.go -- | |
| package a | |
| func _() { | |
| type s struct { | |
| nested struct { | |
| // nested number | |
| number int64 //@loc(nestedNumber, "number") | |
| } | |
| nested2 []struct { | |
| // nested string | |
| str string //@loc(nestedString, "str") | |
| } | |
| x struct { | |
| x struct { | |
| x struct { | |
| x struct { | |
| x struct { | |
| // nested map | |
| m map[string]float64 //@loc(nestedMap, "m") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| var t s | |
| _ = t.nested.number //@hover("number", "number", nestedNumber), def("number", nestedNumber) | |
| _ = t.nested2[0].str //@hover("str", "str", nestedString), def("str", nestedString) | |
| _ = t.x.x.x.x.x.m //@hover("m", "m", nestedMap), def("m", nestedMap) | |
| } | |
| func _() { | |
| var s struct { | |
| // a field | |
| a int //@loc(structA, "a") | |
| // b nested struct | |
| b struct { //@loc(structB, "b") | |
| // c field of nested struct | |
| c int //@loc(structC, "c") | |
| } | |
| } | |
| _ = s.a //@def("a", structA) | |
| _ = s.b //@def("b", structB) | |
| _ = s.b.c //@def("c", structC) | |
| var arr []struct { | |
| // d field | |
| d int //@loc(arrD, "d") | |
| // e nested struct | |
| e struct { //@loc(arrE, "e") | |
| // f field of nested struct | |
| f int //@loc(arrF, "f") | |
| } | |
| } | |
| _ = arr[0].d //@def("d", arrD) | |
| _ = arr[0].e //@def("e", arrE) | |
| _ = arr[0].e.f //@def("f", arrF) | |
| var complex []struct { | |
| c <-chan map[string][]struct { | |
| // h field | |
| h int //@loc(complexH, "h") | |
| // i nested struct | |
| i struct { //@loc(complexI, "i") | |
| // j field of nested struct | |
| j int //@loc(complexJ, "j") | |
| } | |
| } | |
| } | |
| _ = (<-complex[0].c)["0"][0].h //@def("h", complexH) | |
| _ = (<-complex[0].c)["0"][0].i //@def("i", complexI) | |
| _ = (<-complex[0].c)["0"][0].i.j //@def("j", complexJ) | |
| var mapWithStructKey map[struct { //@diag("struct", re"invalid map key") | |
| // X key field | |
| x []string //@loc(mapStructKeyX, "x") | |
| }]int | |
| for k := range mapWithStructKey { | |
| _ = k.x //@def("x", mapStructKeyX) | |
| } | |
| var mapWithStructKeyAndValue map[struct { | |
| // Y key field | |
| y string //@loc(mapStructKeyY, "y") | |
| }]struct { | |
| // X value field | |
| x string //@loc(mapStructValueX, "x") | |
| } | |
| for k, v := range mapWithStructKeyAndValue { | |
| // TODO: we don't show docs for y field because both map key and value | |
| // are structs. And in this case, we parse only map value | |
| _ = k.y //@hover("y", "y", hoverStructKeyY), def("y", mapStructKeyY) | |
| _ = v.x //@hover("x", "x", hoverStructKeyX), def("x", mapStructValueX) | |
| } | |
| var i []map[string]interface { | |
| // open method comment | |
| open() error //@loc(openMethod, "open") | |
| } | |
| i[0]["1"].open() //@hover("pen","open", openMethod), def("open", openMethod) | |
| } | |
| func _() { | |
| test := struct { | |
| // test description | |
| desc string //@loc(testDescription, "desc") | |
| }{} | |
| _ = test.desc //@def("desc", testDescription) | |
| for _, tt := range []struct { | |
| // test input | |
| in map[string][]struct { //@loc(testInput, "in") | |
| // test key | |
| key string //@loc(testInputKey, "key") | |
| // test value | |
| value any //@loc(testInputValue, "value") | |
| } | |
| result struct { | |
| v <-chan struct { | |
| // expected test value | |
| value int //@loc(testResultValue, "value") | |
| } | |
| } | |
| }{} { | |
| _ = tt.in //@def("in", testInput) | |
| _ = tt.in["0"][0].key //@def("key", testInputKey) | |
| _ = tt.in["0"][0].value //@def("value", testInputValue) | |
| _ = (<-tt.result.v).value //@def("value", testResultValue) | |
| } | |
| } | |
| func _() { | |
| getPoints := func() []struct { | |
| // X coord | |
| x int //@loc(returnX, "x") | |
| // Y coord | |
| y int //@loc(returnY, "y") | |
| } { | |
| return nil | |
| } | |
| r := getPoints() | |
| _ = r[0].x //@def("x", returnX) | |
| _ = r[0].y //@def("y", returnY) | |
| } | |
| -- @hoverStructKeyX -- | |
| ```go | |
| field x string | |
| ``` | |
| --- | |
| X value field | |
| -- @hoverStructKeyY -- | |
| ```go | |
| field y string | |
| ``` | |
| --- | |
| Y key field | |
| -- @nestedNumber -- | |
| ```go | |
| field number int64 | |
| ``` | |
| --- | |
| nested number | |
| -- @nestedString -- | |
| ```go | |
| field str string | |
| ``` | |
| --- | |
| nested string | |
| -- @openMethod -- | |
| ```go | |
| func (interface) open() error | |
| ``` | |
| --- | |
| open method comment | |
| -- @nestedMap -- | |
| ```go | |
| field m map[string]float64 | |
| ``` | |
| --- | |
| nested map | |
| -- b/e.go -- | |
| package b | |
| import ( | |
| "fmt" | |
| "godef.test/a" | |
| ) | |
| func useThings() { | |
| t := a.Thing{} //@loc(bStructType, "ing") | |
| fmt.Print(t.Member) //@loc(bMember, "ember") | |
| fmt.Print(a.Other) //@loc(bVar, "ther") | |
| a.Things(nil) //@loc(bFunc, "ings") | |
| } | |
| /*@ | |
| def(bStructType, Thing) | |
| def(bMember, Member) | |
| def(bVar, Other) | |
| def(bFunc, Things) | |
| */ | |
| func _() { | |
| var x any | |
| switch x := x.(type) { //@hover("x", "x", xInterface) | |
| case string: //@loc(eString, "string") | |
| fmt.Println(x) //@hover("x", "x", xString) | |
| case int: //@loc(eInt, "int") | |
| fmt.Println(x) //@hover("x", "x", xInt) | |
| } | |
| } | |
| -- @xInt -- | |
| ```go | |
| var x int | |
| ``` | |
| -- @xInterface -- | |
| ```go | |
| var x any | |
| ``` | |
| -- @xString -- | |
| ```go | |
| var x string | |
| ``` | |
| -- broken/unclosedIf.go -- | |
| package broken | |
| import "fmt" | |
| func unclosedIf() { | |
| if false { | |
| var myUnclosedIf string //@loc(myUnclosedIf, "myUnclosedIf") | |
| fmt.Printf("s = %v\n", myUnclosedIf) //@def("my", myUnclosedIf) | |
| } | |
| func _() {} //@diag("_", re"expected") |