internal/lsp: show human-readable const time.Duration as a comment

The current hover information for constant time.Duration is not very
useful because it displays nanoseconds. So, show formatted duration
as an inline comment.

Fixes golang/go#44667

Change-Id: I6177455fb8932d1914d5cf623c0d9c4eff8f0b3f
GitHub-Last-Rev: e168968012741a1e614c66bc97fe60b196943ed3
GitHub-Pull-Request: golang/tools#281
Reviewed-on: https://go-review.googlesource.com/c/tools/+/297310
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go
index 21e1c57..4b9e45f 100644
--- a/internal/lsp/source/hover.go
+++ b/internal/lsp/source/hover.go
@@ -9,10 +9,12 @@
 	"encoding/json"
 	"fmt"
 	"go/ast"
+	"go/constant"
 	"go/doc"
 	"go/format"
 	"go/types"
 	"strings"
+	"time"
 
 	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/protocol"
@@ -232,6 +234,18 @@
 	switch obj := obj.(type) {
 	case *types.Const:
 		str = fmt.Sprintf("%s = %s", str, obj.Val())
+
+		// Try to add a formatted duration as an inline comment
+		typ, ok := obj.Type().(*types.Named)
+		if !ok {
+			break
+		}
+		pkg := typ.Obj().Pkg()
+		if pkg.Path() == "time" && pkg.Scope().Lookup("Duration") != nil {
+			if d, ok := constant.Int64Val(obj.Val()); ok {
+				str += " // " + time.Duration(d).String()
+			}
+		}
 	}
 	return str
 }
diff --git a/internal/lsp/testdata/godef/a/g.go b/internal/lsp/testdata/godef/a/g.go
new file mode 100644
index 0000000..4f31857
--- /dev/null
+++ b/internal/lsp/testdata/godef/a/g.go
@@ -0,0 +1,6 @@
+package a
+
+import "time"
+
+// dur is a constant of type time.Duration.
+const dur = 15*time.Minute + 10*time.Second + 350*time.Millisecond //@dur,hover("dur", dur)
diff --git a/internal/lsp/testdata/godef/a/g.go.golden b/internal/lsp/testdata/godef/a/g.go.golden
new file mode 100644
index 0000000..d46ff04
--- /dev/null
+++ b/internal/lsp/testdata/godef/a/g.go.golden
@@ -0,0 +1,6 @@
+-- dur-hover --
+```go
+const dur time.Duration = 910350000000 // 15m10.35s
+```
+
+dur is a constant of type time\.Duration\.
diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden
index f9b6c38..e0b6366 100644
--- a/internal/lsp/testdata/summary.txt.golden
+++ b/internal/lsp/testdata/summary.txt.golden
@@ -15,7 +15,7 @@
 SemanticTokenCount = 3
 SuggestedFixCount = 40
 FunctionExtractionCount = 12
-DefinitionsCount = 64
+DefinitionsCount = 65
 TypeDefinitionsCount = 2
 HighlightsCount = 69
 ReferencesCount = 25