mirror of
https://github.com/golang/go
synced 2024-11-18 12:34:42 -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:
parent
99d11d0e63
commit
7b8e75db28
@ -9,7 +9,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/lsp/source"
|
"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...)
|
links = append(links, l...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return links, nil
|
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
|
var links []protocol.DocumentLink
|
||||||
for _, urlIndex := range view.Options().URLRegexp.FindAllIndex([]byte(src), -1) {
|
for _, index := range view.Options().URLRegexp.FindAllIndex([]byte(src), -1) {
|
||||||
var target string
|
start, end := index[0], index[1]
|
||||||
start := urlIndex[0]
|
|
||||||
end := urlIndex[1]
|
|
||||||
startPos := token.Pos(int(pos) + start)
|
startPos := token.Pos(int(pos) + start)
|
||||||
endPos := token.Pos(int(pos) + end)
|
endPos := token.Pos(int(pos) + end)
|
||||||
target = src[start:end]
|
target := src[start:end]
|
||||||
l, err := toProtocolLink(view, mapper, target, startPos, endPos)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -102,12 +119,24 @@ func findLinksInString(view source.View, src string, pos token.Pos, mapper *prot
|
|||||||
return links, nil
|
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()
|
spn, err := span.NewRange(view.Session().Cache().FileSet(), start, end).Span()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return protocol.DocumentLink{}, err
|
return protocol.DocumentLink{}, err
|
||||||
}
|
}
|
||||||
rng, err := mapper.Range(spn)
|
rng, err := m.Range(spn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return protocol.DocumentLink{}, err
|
return protocol.DocumentLink{}, err
|
||||||
}
|
}
|
||||||
|
3
internal/lsp/testdata/links/links.go
vendored
3
internal/lsp/testdata/links/links.go
vendored
@ -22,4 +22,7 @@ func Foo() string {
|
|||||||
|
|
||||||
url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal")
|
url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal")
|
||||||
return url
|
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")
|
||||||
}
|
}
|
||||||
|
2
internal/lsp/testdata/summary.txt.golden
vendored
2
internal/lsp/testdata/summary.txt.golden
vendored
@ -19,6 +19,6 @@ RenamesCount = 22
|
|||||||
PrepareRenamesCount = 8
|
PrepareRenamesCount = 8
|
||||||
SymbolsCount = 1
|
SymbolsCount = 1
|
||||||
SignaturesCount = 22
|
SignaturesCount = 22
|
||||||
LinksCount = 6
|
LinksCount = 8
|
||||||
ImplementationsCount = 5
|
ImplementationsCount = 5
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user