From 5a8dccf5b48ae388eebac31f4077f14adda4dbc6 Mon Sep 17 00:00:00 2001 From: Ian Cottrell Date: Fri, 22 Mar 2019 16:43:20 -0400 Subject: [PATCH] go/packages/packagestest: convert to the span library Change-Id: Ib8984dd0828e3bb0b49eaa1604649300a4d54306 Reviewed-on: https://go-review.googlesource.com/c/tools/+/168900 Reviewed-by: Michael Matloob --- go/packages/packagestest/expect.go | 49 ++++++++++++++++--------- go/packages/packagestest/expect_test.go | 3 +- go/packages/packagestest/export.go | 3 +- internal/lsp/cmd/definition_test.go | 30 +++++++-------- 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/go/packages/packagestest/expect.go b/go/packages/packagestest/expect.go index 30f42352..925e417a 100644 --- a/go/packages/packagestest/expect.go +++ b/go/packages/packagestest/expect.go @@ -13,6 +13,7 @@ import ( "golang.org/x/tools/go/expect" "golang.org/x/tools/go/packages" + "golang.org/x/tools/internal/span" ) const ( @@ -116,15 +117,14 @@ func (e *Exported) Expect(methods map[string]interface{}) error { return nil } -type Range struct { - Start token.Pos - End token.Pos -} +// Range is a type alias for span.Range for backwards compatability, prefer +// using span.Range directly. +type Range = span.Range // Mark adds a new marker to the known set. func (e *Exported) Mark(name string, r Range) { if e.markers == nil { - e.markers = make(map[string]Range) + e.markers = make(map[string]span.Range) } e.markers[name] = r } @@ -166,7 +166,7 @@ func (e *Exported) getMarkers() error { return nil } // set markers early so that we don't call getMarkers again from Expect - e.markers = make(map[string]Range) + e.markers = make(map[string]span.Range) return e.Expect(map[string]interface{}{ markMethod: e.Mark, }) @@ -177,7 +177,8 @@ var ( identifierType = reflect.TypeOf(expect.Identifier("")) posType = reflect.TypeOf(token.Pos(0)) positionType = reflect.TypeOf(token.Position{}) - rangeType = reflect.TypeOf(Range{}) + rangeType = reflect.TypeOf(span.Range{}) + spanType = reflect.TypeOf(span.Span{}) fsetType = reflect.TypeOf((*token.FileSet)(nil)) regexType = reflect.TypeOf((*regexp.Regexp)(nil)) exportedType = reflect.TypeOf((*Exported)(nil)) @@ -239,6 +240,18 @@ func (e *Exported) buildConverter(pt reflect.Type) (converter, error) { } return reflect.ValueOf(r), remains, nil }, nil + case pt == spanType: + return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) { + r, remains, err := e.rangeConverter(n, args) + if err != nil { + return reflect.Value{}, nil, err + } + spn, err := r.Span() + if err != nil { + return reflect.Value{}, nil, err + } + return reflect.ValueOf(spn), remains, nil + }, nil case pt == identifierType: return func(n *expect.Note, args []interface{}) (reflect.Value, []interface{}, error) { if len(args) < 1 { @@ -340,9 +353,9 @@ func (e *Exported) buildConverter(pt reflect.Type) (converter, error) { } } -func (e *Exported) rangeConverter(n *expect.Note, args []interface{}) (Range, []interface{}, error) { +func (e *Exported) rangeConverter(n *expect.Note, args []interface{}) (span.Range, []interface{}, error) { if len(args) < 1 { - return Range{}, nil, fmt.Errorf("missing argument") + return span.Range{}, nil, fmt.Errorf("missing argument") } arg := args[0] args = args[1:] @@ -354,34 +367,34 @@ func (e *Exported) rangeConverter(n *expect.Note, args []interface{}) (Range, [] // end of file identifier, look up the current file f := e.fset.File(n.Pos) eof := f.Pos(f.Size()) - return Range{Start: eof, End: token.NoPos}, args, nil + return span.Range{FileSet: e.fset, Start: eof, End: token.NoPos}, args, nil default: // look up an marker by name mark, ok := e.markers[string(arg)] if !ok { - return Range{}, nil, fmt.Errorf("cannot find marker %v", arg) + return span.Range{}, nil, fmt.Errorf("cannot find marker %v", arg) } return mark, args, nil } case string: start, end, err := expect.MatchBefore(e.fset, e.FileContents, n.Pos, arg) if err != nil { - return Range{}, nil, err + return span.Range{}, nil, err } if start == token.NoPos { - return Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg) + return span.Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg) } - return Range{Start: start, End: end}, args, nil + return span.Range{FileSet: e.fset, Start: start, End: end}, args, nil case *regexp.Regexp: start, end, err := expect.MatchBefore(e.fset, e.FileContents, n.Pos, arg) if err != nil { - return Range{}, nil, err + return span.Range{}, nil, err } if start == token.NoPos { - return Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg) + return span.Range{}, nil, fmt.Errorf("%v: pattern %s did not match", e.fset.Position(n.Pos), arg) } - return Range{Start: start, End: end}, args, nil + return span.Range{FileSet: e.fset, Start: start, End: end}, args, nil default: - return Range{}, nil, fmt.Errorf("cannot convert %v to pos", arg) + return span.Range{}, nil, fmt.Errorf("cannot convert %v to pos", arg) } } diff --git a/go/packages/packagestest/expect_test.go b/go/packages/packagestest/expect_test.go index a51946d6..527c8d73 100644 --- a/go/packages/packagestest/expect_test.go +++ b/go/packages/packagestest/expect_test.go @@ -10,6 +10,7 @@ import ( "golang.org/x/tools/go/expect" "golang.org/x/tools/go/packages/packagestest" + "golang.org/x/tools/internal/span" ) func TestExpect(t *testing.T) { @@ -42,7 +43,7 @@ func TestExpect(t *testing.T) { } }, "directNote": func(n *expect.Note) {}, - "range": func(r packagestest.Range) { + "range": func(r span.Range) { if r.Start == token.NoPos || r.Start == 0 { t.Errorf("Range had no valid starting position") } diff --git a/go/packages/packagestest/export.go b/go/packages/packagestest/export.go index ea478a37..e927313e 100644 --- a/go/packages/packagestest/export.go +++ b/go/packages/packagestest/export.go @@ -24,6 +24,7 @@ import ( "golang.org/x/tools/go/expect" "golang.org/x/tools/go/packages" + "golang.org/x/tools/internal/span" ) var ( @@ -66,7 +67,7 @@ type Exported struct { written map[string]map[string]string // the full set of exported files fset *token.FileSet // The file set used when parsing expectations notes []*expect.Note // The list of expectations extracted from go source files - markers map[string]Range // The set of markers extracted from go source files + markers map[string]span.Range // The set of markers extracted from go source files } // Exporter implementations are responsible for converting from the generic description of some diff --git a/internal/lsp/cmd/definition_test.go b/internal/lsp/cmd/definition_test.go index c19957f1..e9e9cb00 100644 --- a/internal/lsp/cmd/definition_test.go +++ b/internal/lsp/cmd/definition_test.go @@ -8,7 +8,6 @@ import ( "context" "flag" "fmt" - "go/token" "io/ioutil" "os" "os/exec" @@ -60,46 +59,43 @@ func TestDefinition(t *testing.T) { defer exported.Cleanup() count := 0 if err := exported.Expect(map[string]interface{}{ - "definition": func(fset *token.FileSet, src token.Pos, flags string, def packagestest.Range, match string) { + "definition": func(src span.Span, flags string, def span.Span, match string) { count++ args := []string{"query"} if flags != "" { args = append(args, strings.Split(flags, " ")...) } args = append(args, "definition") - f := fset.File(src) - spn := span.New(span.FileURI(f.Name()), span.NewPoint(0, 0, f.Offset(src)), span.Point{}) - args = append(args, fmt.Sprint(spn)) + args = append(args, fmt.Sprint(src)) app := &cmd.Application{} app.Config = *exported.Config got := captureStdOut(t, func() { tool.Main(context.Background(), app, args) }) - start := fset.Position(def.Start) - end := fset.Position(def.End) expect := os.Expand(match, func(name string) string { switch name { case "file": - return start.Filename + fname, _ := def.URI().Filename() + return fname case "efile": - qfile := strconv.Quote(start.Filename) + fname, _ := def.URI().Filename() + qfile := strconv.Quote(fname) return qfile[1 : len(qfile)-1] case "euri": - uri := span.FileURI(start.Filename) - quri := strconv.Quote(string(uri)) + quri := strconv.Quote(string(def.URI())) return quri[1 : len(quri)-1] case "line": - return fmt.Sprint(start.Line) + return fmt.Sprint(def.Start().Line()) case "col": - return fmt.Sprint(start.Column) + return fmt.Sprint(def.Start().Column()) case "offset": - return fmt.Sprint(start.Offset) + return fmt.Sprint(def.Start().Offset()) case "eline": - return fmt.Sprint(end.Line) + return fmt.Sprint(def.End().Line()) case "ecol": - return fmt.Sprint(end.Column) + return fmt.Sprint(def.End().Column()) case "eoffset": - return fmt.Sprint(end.Offset) + return fmt.Sprint(def.End().Offset()) default: return name }