internal/lsp: support hover for *ast.ImportSpec

Since 'IdentifierInfo' doesn't contain ast node of import spec,
gopls will construct an empty string under plaintext mode and
'```go\n\n```' under markdown mode for *ast.ImportSpec. For now,
the hovering result of import spec is the corresponding node
format.

Fixes golang/go#33000

Change-Id: I4c25782ddb5bcc557ace82f46d480316b0b90509
GitHub-Last-Rev: 150728f401c5f9b161b557584ad3250f46e50869
GitHub-Pull-Request: golang/tools#134
Reviewed-on: https://go-review.googlesource.com/c/tools/+/185357
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go
index 9fdfe1b..a537f95 100644
--- a/internal/lsp/source/hover.go
+++ b/internal/lsp/source/hover.go
@@ -84,6 +84,8 @@
 	defer ts.End()
 	obj := d.obj
 	switch node := d.node.(type) {
+	case *ast.ImportSpec:
+		return &documentation{node, nil}, nil
 	case *ast.GenDecl:
 		switch obj := obj.(type) {
 		case *types.TypeName, *types.Var, *types.Const, *types.Func:
diff --git a/internal/lsp/source/identifier.go b/internal/lsp/source/identifier.go
index 061c229..583774e 100644
--- a/internal/lsp/source/identifier.go
+++ b/internal/lsp/source/identifier.go
@@ -74,7 +74,7 @@
 		return nil, fmt.Errorf("pkg for %s is ill-typed", f.URI())
 	}
 	// Handle import specs separately, as there is no formal position for a package declaration.
-	if result, err := importSpec(ctx, f, file, pkg, pos); result != nil || err != nil {
+	if result, err := importSpec(f, file, pkg, pos); result != nil || err != nil {
 		return result, err
 	}
 	path, _ := astutil.PathEnclosingInterval(file, pos, pos)
@@ -267,7 +267,7 @@
 }
 
 // importSpec handles positions inside of an *ast.ImportSpec.
-func importSpec(ctx context.Context, f GoFile, fAST *ast.File, pkg Package, pos token.Pos) (*IdentifierInfo, error) {
+func importSpec(f GoFile, fAST *ast.File, pkg Package, pos token.Pos) (*IdentifierInfo, error) {
 	var imp *ast.ImportSpec
 	for _, spec := range fAST.Imports {
 		if spec.Pos() <= pos && pos < spec.End() {
@@ -306,6 +306,7 @@
 		return nil, fmt.Errorf("package %q has no files", importPath)
 	}
 	result.decl.rng = span.NewRange(f.FileSet(), dest.Name.Pos(), dest.Name.End())
+	result.decl.node = imp
 	return result, nil
 }
 
diff --git a/internal/lsp/testdata/godef/b/b.go.golden b/internal/lsp/testdata/godef/b/b.go.golden
index 444b985..fb534d2 100644
--- a/internal/lsp/testdata/godef/b/b.go.golden
+++ b/internal/lsp/testdata/godef/b/b.go.golden
@@ -66,6 +66,7 @@
 }
 
 -- PackageFoo-hover --
+myFoo "golang.org/x/tools/internal/lsp/foo" //@godef("foo", PackageFoo),godef("myFoo", PackageFoo)
 
 -- S1-definition --
 godef/b/b.go:8:6-8: defined here as S1 struct {