Thanks @brianpursley. I commented on your CL, but I think we should use the type-checker to compute the method set for us, rather than trying to resolve it ourselves (resolving a method set is a surprisingly difficult task!).
You can get the type by looking it up in types.Info.Types, and then pass it to NewMethodSet to compute a representation of its methods. This will work for more than just structs: any defined type may have methods. We probably don't want to do this for interface types though, as I think it will be redundant with the type definition.
Other questions to answer:
do we want to show all methods (included those that are added via embedding), or just those that are directly defined (if just the latter, maybe we don't even need NewMethodSet and could just use the go/types.Named API.
how do we want to qualify names in the type signature. Relative to the package defining the type, or relative to the current package being hovered? go/types.TypeString and go/types.ObjectString provide APIs for formatting types and objects with a custom qualifier
how best do we present the methods visually? Do we want to include their receiver, or just show their name and function signature?
Cool! This is a great place to contribute as the change is mostly isolated to hover.go (though our hover handling is a bit hard to follow).
Something like what you propose looks good to me. IIRC if we use go/types.TypeString or go/types.ObjectString, we will format the receiver (func (*MyStruct) Add(x int) int), which we probably don't want. So we may need to do a bit of massaging to get it into that form.