1
0
mirror of https://github.com/golang/go synced 2024-11-18 10:14:45 -07:00

internal/lsp: create links for golang/go#1234-style strings

This change treats text of the format golang/go#1234 as a link to the Go
issue tracker. This will improve the readability of TODOs that include a
link to an issue, since it doesn't have to be an actual link.

Change-Id: I27606ceb9cbb15bc6bfb1d7aa660d3f4fdd08739
Reviewed-on: https://go-review.googlesource.com/c/tools/+/212518
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Rebecca Stambler 2019-12-24 15:58:48 -05:00
parent 99d11d0e63
commit 7b8e75db28
3 changed files with 43 additions and 11 deletions

View File

@ -9,7 +9,9 @@ import (
"fmt"
"go/ast"
"go/token"
"regexp"
"strconv"
"sync"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
@ -80,20 +82,35 @@ func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLink
links = append(links, l...)
}
}
return links, nil
}
func findLinksInString(view source.View, src string, pos token.Pos, mapper *protocol.ColumnMapper) ([]protocol.DocumentLink, error) {
func findLinksInString(view source.View, src string, pos token.Pos, m *protocol.ColumnMapper) ([]protocol.DocumentLink, error) {
var links []protocol.DocumentLink
for _, urlIndex := range view.Options().URLRegexp.FindAllIndex([]byte(src), -1) {
var target string
start := urlIndex[0]
end := urlIndex[1]
for _, index := range view.Options().URLRegexp.FindAllIndex([]byte(src), -1) {
start, end := index[0], index[1]
startPos := token.Pos(int(pos) + start)
endPos := token.Pos(int(pos) + end)
target = src[start:end]
l, err := toProtocolLink(view, mapper, target, startPos, endPos)
target := src[start:end]
l, err := toProtocolLink(view, m, target, startPos, endPos)
if err != nil {
return nil, err
}
links = append(links, l)
}
// Handle golang/go#1234-style links.
r := getIssueRegexp()
for _, index := range r.FindAllIndex([]byte(src), -1) {
start, end := index[0], index[1]
startPos := token.Pos(int(pos) + start)
endPos := token.Pos(int(pos) + end)
matches := r.FindStringSubmatch(src)
if len(matches) < 4 {
continue
}
org, repo, number := matches[1], matches[2], matches[3]
target := fmt.Sprintf("https://github.com/%s/%s/issues/%s", org, repo, number)
l, err := toProtocolLink(view, m, target, startPos, endPos)
if err != nil {
return nil, err
}
@ -102,12 +119,24 @@ func findLinksInString(view source.View, src string, pos token.Pos, mapper *prot
return links, nil
}
func toProtocolLink(view source.View, mapper *protocol.ColumnMapper, target string, start, end token.Pos) (protocol.DocumentLink, error) {
func getIssueRegexp() *regexp.Regexp {
once.Do(func() {
issueRegexp = regexp.MustCompile(`(\w+)/([\w-]+)#([0-9]+)`)
})
return issueRegexp
}
var (
once sync.Once
issueRegexp *regexp.Regexp
)
func toProtocolLink(view source.View, m *protocol.ColumnMapper, target string, start, end token.Pos) (protocol.DocumentLink, error) {
spn, err := span.NewRange(view.Session().Cache().FileSet(), start, end).Span()
if err != nil {
return protocol.DocumentLink{}, err
}
rng, err := mapper.Range(spn)
rng, err := m.Range(spn)
if err != nil {
return protocol.DocumentLink{}, err
}

View File

@ -22,4 +22,7 @@ func Foo() string {
url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal")
return url
// TODO(golang/go#1234): Link the relevant issue. //@link("golang/go#1234", "https://github.com/golang/go/issues/1234")
// TODO(microsoft/vscode-go#12): Another issue. //@link("microsoft/vscode-go#12", "https://github.com/microsoft/vscode-go/issues/12")
}

View File

@ -19,6 +19,6 @@ RenamesCount = 22
PrepareRenamesCount = 8
SymbolsCount = 1
SignaturesCount = 22
LinksCount = 6
LinksCount = 8
ImplementationsCount = 5