зеркало из https://github.com/golang/tools.git
gopls/internal/lsp/source: eliminate a couple uses of posToMappedRange
Eliminate a couple uses of posToMappedRange, which potentially type-checks, where it is clearly unnecessary. Also improve test output for highlight. Updates golang/go#57987 Updates golang/go#54845 Change-Id: I5580bf6431def0a6ee635e394932934ec7fe1afb Reviewed-on: https://go-review.googlesource.com/c/tools/+/463556 TryBot-Result: Gopher Robot <gobot@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> Run-TryBot: Robert Findley <rfindley@google.com>
This commit is contained in:
Родитель
031e6e6d06
Коммит
60782e9bdb
|
@ -771,45 +771,56 @@ func (r *runner) Implementation(t *testing.T, spn span.Span, wantSpans []span.Sp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) {
|
func (r *runner) Highlight(t *testing.T, src span.Span, spans []span.Span) {
|
||||||
m, err := r.data.Mapper(src.URI())
|
m, err := r.data.Mapper(src.URI())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
loc, err := m.SpanLocation(src)
|
loc, err := m.SpanLocation(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed for %v: %v", locations[0], err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
tdpp := protocol.TextDocumentPositionParams{
|
tdpp := protocol.TextDocumentPositionParams{
|
||||||
TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
|
TextDocument: protocol.TextDocumentIdentifier{
|
||||||
|
URI: loc.URI,
|
||||||
|
},
|
||||||
Position: loc.Range.Start,
|
Position: loc.Range.Start,
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Mapper.SpanDocumentPosition(%v) failed: %v", src, err)
|
||||||
|
}
|
||||||
params := &protocol.DocumentHighlightParams{
|
params := &protocol.DocumentHighlightParams{
|
||||||
TextDocumentPositionParams: tdpp,
|
TextDocumentPositionParams: tdpp,
|
||||||
}
|
}
|
||||||
highlights, err := r.server.DocumentHighlight(r.ctx, params)
|
highlights, err := r.server.DocumentHighlight(r.ctx, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatalf("DocumentHighlight(%v) failed: %v", params, err)
|
||||||
}
|
}
|
||||||
if len(highlights) != len(locations) {
|
var got []protocol.Range
|
||||||
t.Fatalf("got %d highlights for highlight at %v:%v:%v, expected %d", len(highlights), src.URI().Filename(), src.Start().Line(), src.Start().Column(), len(locations))
|
for _, h := range highlights {
|
||||||
|
got = append(got, h.Range)
|
||||||
}
|
}
|
||||||
// Check to make sure highlights have a valid range.
|
|
||||||
var results []span.Span
|
var want []protocol.Range
|
||||||
for i := range highlights {
|
for _, s := range spans {
|
||||||
h, err := m.RangeSpan(highlights[i].Range)
|
rng, err := m.SpanRange(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed for %v: %v", highlights[i], err)
|
t.Fatalf("Mapper.SpanRange(%v) failed: %v", s, err)
|
||||||
}
|
}
|
||||||
results = append(results, h)
|
want = append(want, rng)
|
||||||
}
|
}
|
||||||
// Sort results to make tests deterministic since DocumentHighlight uses a map.
|
|
||||||
span.SortSpans(results)
|
sortRanges := func(s []protocol.Range) {
|
||||||
// Check to make sure all the expected highlights are found.
|
sort.Slice(s, func(i, j int) bool {
|
||||||
for i := range results {
|
return protocol.CompareRange(s[i], s[j]) < 0
|
||||||
if results[i] != locations[i] {
|
})
|
||||||
t.Errorf("want %v, got %v\n", locations[i], results[i])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortRanges(got)
|
||||||
|
sortRanges(want)
|
||||||
|
|
||||||
|
if diff := cmp.Diff(want, got); diff != "" {
|
||||||
|
t.Errorf("DocumentHighlight(%v) mismatch (-want +got):\n%s", src, diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,28 +48,28 @@ func Highlight(ctx context.Context, snapshot Snapshot, fh FileHandle, position p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result, err := highlightPath(pkg, path)
|
result, err := highlightPath(path, pgf.File, pkg.GetTypesInfo())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var ranges []protocol.Range
|
var ranges []protocol.Range
|
||||||
for rng := range result {
|
for rng := range result {
|
||||||
mRng, err := posToMappedRange(ctx, snapshot, pkg, rng.start, rng.end)
|
rng, err := pgf.PosRange(rng.start, rng.end)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ranges = append(ranges, mRng.Range())
|
ranges = append(ranges, rng)
|
||||||
}
|
}
|
||||||
return ranges, nil
|
return ranges, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func highlightPath(pkg Package, path []ast.Node) (map[posRange]struct{}, error) {
|
func highlightPath(path []ast.Node, file *ast.File, info *types.Info) (map[posRange]struct{}, error) {
|
||||||
result := make(map[posRange]struct{})
|
result := make(map[posRange]struct{})
|
||||||
switch node := path[0].(type) {
|
switch node := path[0].(type) {
|
||||||
case *ast.BasicLit:
|
case *ast.BasicLit:
|
||||||
if len(path) > 1 {
|
if len(path) > 1 {
|
||||||
if _, ok := path[1].(*ast.ImportSpec); ok {
|
if _, ok := path[1].(*ast.ImportSpec); ok {
|
||||||
err := highlightImportUses(pkg, path, result)
|
err := highlightImportUses(path, info, result)
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,9 @@ func highlightPath(pkg Package, path []ast.Node) (map[posRange]struct{}, error)
|
||||||
case *ast.ReturnStmt, *ast.FuncDecl, *ast.FuncType:
|
case *ast.ReturnStmt, *ast.FuncDecl, *ast.FuncType:
|
||||||
highlightFuncControlFlow(path, result)
|
highlightFuncControlFlow(path, result)
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
highlightIdentifiers(pkg, path, result)
|
// Check if ident is inside return or func decl.
|
||||||
|
highlightFuncControlFlow(path, result)
|
||||||
|
highlightIdentifier(node, file, info, result)
|
||||||
case *ast.ForStmt, *ast.RangeStmt:
|
case *ast.ForStmt, *ast.RangeStmt:
|
||||||
highlightLoopControlFlow(path, result)
|
highlightLoopControlFlow(path, result)
|
||||||
case *ast.SwitchStmt:
|
case *ast.SwitchStmt:
|
||||||
|
@ -426,7 +428,7 @@ func labelDecl(n *ast.Ident) *ast.Ident {
|
||||||
return stmt.Label
|
return stmt.Label
|
||||||
}
|
}
|
||||||
|
|
||||||
func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struct{}) error {
|
func highlightImportUses(path []ast.Node, info *types.Info, result map[posRange]struct{}) error {
|
||||||
basicLit, ok := path[0].(*ast.BasicLit)
|
basicLit, ok := path[0].(*ast.BasicLit)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("highlightImportUses called with an ast.Node of type %T", basicLit)
|
return fmt.Errorf("highlightImportUses called with an ast.Node of type %T", basicLit)
|
||||||
|
@ -440,7 +442,7 @@ func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struc
|
||||||
if !ok {
|
if !ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
obj, ok := pkg.GetTypesInfo().ObjectOf(n).(*types.PkgName)
|
obj, ok := info.ObjectOf(n).(*types.PkgName)
|
||||||
if !ok {
|
if !ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -453,19 +455,16 @@ func highlightImportUses(pkg Package, path []ast.Node, result map[posRange]struc
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func highlightIdentifiers(pkg Package, path []ast.Node, result map[posRange]struct{}) error {
|
func highlightIdentifier(id *ast.Ident, file *ast.File, info *types.Info, result map[posRange]struct{}) {
|
||||||
id, ok := path[0].(*ast.Ident)
|
// TODO(rfindley): idObj may be nil. Note that returning early in this case
|
||||||
if !ok {
|
// causes tests to fail (because the nObj == idObj check below was succeeded
|
||||||
return fmt.Errorf("highlightIdentifiers called with an ast.Node of type %T", id)
|
// for nil == nil!)
|
||||||
}
|
//
|
||||||
// Check if ident is inside return or func decl.
|
// Revisit this. If ObjectOf is nil, there are type errors, and it seems
|
||||||
highlightFuncControlFlow(path, result)
|
// reasonable for identifier highlighting not to work.
|
||||||
|
idObj := info.ObjectOf(id)
|
||||||
// TODO: maybe check if ident is a reserved word, if true then don't continue and return results.
|
|
||||||
|
|
||||||
idObj := pkg.GetTypesInfo().ObjectOf(id)
|
|
||||||
pkgObj, isImported := idObj.(*types.PkgName)
|
pkgObj, isImported := idObj.(*types.PkgName)
|
||||||
ast.Inspect(path[len(path)-1], func(node ast.Node) bool {
|
ast.Inspect(file, func(node ast.Node) bool {
|
||||||
if imp, ok := node.(*ast.ImportSpec); ok && isImported {
|
if imp, ok := node.(*ast.ImportSpec); ok && isImported {
|
||||||
highlightImport(pkgObj, imp, result)
|
highlightImport(pkgObj, imp, result)
|
||||||
}
|
}
|
||||||
|
@ -476,12 +475,11 @@ func highlightIdentifiers(pkg Package, path []ast.Node, result map[posRange]stru
|
||||||
if n.Name != id.Name {
|
if n.Name != id.Name {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if nObj := pkg.GetTypesInfo().ObjectOf(n); nObj == idObj {
|
if nObj := info.ObjectOf(n); nObj == idObj {
|
||||||
result[posRange{start: n.Pos(), end: n.End()}] = struct{}{}
|
result[posRange{start: n.Pos(), end: n.End()}] = struct{}{}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func highlightImport(obj *types.PkgName, imp *ast.ImportSpec, result map[posRange]struct{}) {
|
func highlightImport(obj *types.PkgName, imp *ast.ImportSpec, result map[posRange]struct{}) {
|
||||||
|
|
|
@ -141,7 +141,12 @@ func references(ctx context.Context, snapshot Snapshot, qos []qualifiedObject, i
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seen[key] = true
|
seen[key] = true
|
||||||
rng, err := posToMappedRange(ctx, snapshot, pkg, ident.Pos(), ident.End())
|
filename := pkg.FileSet().File(ident.Pos()).Name()
|
||||||
|
pgf, err := pkg.File(span.URIFromPath(filename))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rng, err := pgf.PosMappedRange(ident.Pos(), ident.End())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче