blob: 9b2e7ec2ce30a1174abee81448317af3d94ef4cc [file] [log] [blame]
This test was ported from 'godef' in the old marker tests.
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
-- flags --
-min_go=go1.20
-- 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 := interface{}(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 interface{}
```
-- 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 interface{} //@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 interface{}
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 interface{}
```
-- @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")