internal/lsp: make the guru emulation tests slightly looser with a different matching system

We now match only the things we realy need to, to allow the description to vary more.

Change-Id: Ib3591c41ed5a5c725f2a3efb180ba17f808de51a
Reviewed-on: https://go-review.googlesource.com/c/tools/+/170341
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Ian Cottrell 2019-04-02 12:06:03 -04:00
parent 8a44e74612
commit 923d258130
3 changed files with 125 additions and 85 deletions

View File

@ -32,7 +32,7 @@ type definition struct {
src span.Span
flags string
def span.Span
match string
pattern pattern
}
type definitions map[span.Span]definition
@ -68,6 +68,7 @@ func (l definitions) godef(src, def span.Span) {
l[src] = definition{
src: src,
def: def,
pattern: newPattern("", def),
}
}
@ -75,6 +76,7 @@ func (l definitions) typdef(src, def span.Span) {
l[src] = definition{
src: src,
def: def,
pattern: newPattern("", def),
}
}
@ -83,7 +85,7 @@ func (l definitions) definition(src span.Span, flags string, def span.Span, matc
src: src,
flags: flags,
def: def,
match: match,
pattern: newPattern(match, def),
}
}
@ -104,42 +106,8 @@ func (l definitions) testDefinitions(t *testing.T, e *packagestest.Exported) {
got := captureStdOut(t, func() {
tool.Main(context.Background(), app, args)
})
if d.match == "" {
expect := fmt.Sprint(d.def)
if !strings.HasPrefix(got, expect) {
t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, expect, got)
}
} else {
expect := os.Expand(d.match, func(name string) string {
switch name {
case "file":
fname, _ := d.def.URI().Filename()
return fname
case "efile":
fname, _ := d.def.URI().Filename()
qfile := strconv.Quote(fname)
return qfile[1 : len(qfile)-1]
case "euri":
quri := strconv.Quote(string(d.def.URI()))
return quri[1 : len(quri)-1]
case "line":
return fmt.Sprint(d.def.Start().Line())
case "col":
return fmt.Sprint(d.def.Start().Column())
case "offset":
return fmt.Sprint(d.def.Start().Offset())
case "eline":
return fmt.Sprint(d.def.End().Line())
case "ecol":
return fmt.Sprint(d.def.End().Column())
case "eoffset":
return fmt.Sprint(d.def.End().Offset())
default:
return name
}
})
if expect != got {
t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, expect, got)
if !d.pattern.matches(got) {
t.Errorf("definition %v\nexpected:\n%s\ngot:\n%s", args, d.pattern, got)
}
if *verifyGuru {
moduleMode := e.File(e.Modules[0].Name, "go.mod") != ""
@ -171,9 +139,8 @@ func (l definitions) testDefinitions(t *testing.T, e *packagestest.Exported) {
t.Errorf("Could not run guru %v: %v\n%s", guruArgs, err, out)
} else {
guru := strings.TrimSpace(string(out))
if !strings.HasPrefix(expect, guru) {
t.Errorf("definition %v\nexpected:\n%s\nguru gave:\n%s", args, expect, guru)
}
if !d.pattern.matches(guru) {
t.Errorf("definition %v\nexpected:\n%s\nguru gave:\n%s", args, d.pattern, guru)
}
}
}
@ -187,3 +154,74 @@ func (l definitions) testTypeDefinitions(t *testing.T, e *packagestest.Exported)
}
//TODO: add command line type definition tests when it works
}
type pattern struct {
raw string
expanded []string
matchAll bool
}
func newPattern(s string, def span.Span) pattern {
p := pattern{raw: s}
if s == "" {
p.expanded = []string{fmt.Sprintf("%v: ", def)}
return p
}
p.matchAll = strings.HasSuffix(s, "$$")
for _, fragment := range strings.Split(s, "$$") {
p.expanded = append(p.expanded, os.Expand(fragment, func(name string) string {
switch name {
case "file":
fname, _ := def.URI().Filename()
return fname
case "efile":
fname, _ := def.URI().Filename()
qfile := strconv.Quote(fname)
return qfile[1 : len(qfile)-1]
case "euri":
quri := strconv.Quote(string(def.URI()))
return quri[1 : len(quri)-1]
case "line":
return fmt.Sprint(def.Start().Line())
case "col":
return fmt.Sprint(def.Start().Column())
case "offset":
return fmt.Sprint(def.Start().Offset())
case "eline":
return fmt.Sprint(def.End().Line())
case "ecol":
return fmt.Sprint(def.End().Column())
case "eoffset":
return fmt.Sprint(def.End().Offset())
default:
return name
}
}))
}
return p
}
func (p pattern) String() string {
return strings.Join(p.expanded, "$$")
}
func (p pattern) matches(s string) bool {
if len(p.expanded) == 0 {
return false
}
if !strings.HasPrefix(s, p.expanded[0]) {
return false
}
remains := s[len(p.expanded[0]):]
for _, fragment := range p.expanded[1:] {
i := strings.Index(remains, fragment)
if i < 0 {
return false
}
remains = remains[i+len(fragment):]
}
if !p.matchAll {
return true
}
return len(remains) == 0
}

View File

@ -1,5 +1,7 @@
package a
import "fmt"
type Thing struct { //@Thing
Member string //@Member
}
@ -33,7 +35,7 @@ definition(aVar, "", Other, "$file:$line:$col-$ecol: defined here as var Other T
definition(aVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var Other")
definition(aFunc, "", Things, "$file:$line:$col-$ecol: defined here as func Things(val []string) []Thing")
definition(aFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func Things(val []string) []Thing")
definition(aFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func Things")
definition(aMethod, "", Method, "$file:$line:$col-$ecol: defined here as func (Thing).Method(i int) string")
definition(aMethod, "-emulate=guru", Method, "$file:$line:$col: defined here as func (Thing).Method(i int) string")
@ -63,6 +65,6 @@ definition(aStructType, "-json", Thing, `{
}`)
definition(aStructType, "-json -emulate=guru", Thing, `{
"objpos": "$efile:$line:$col",
"desc": "type Thing"
"desc": "type Thing$$"
}`)
*/

View File

@ -15,14 +15,14 @@ func useThings() {
/*@
definition(bStructType, "", Thing, "$file:$line:$col-$ecol: defined here as type a.Thing struct{Member string}")
definition(bStructType, "-emulate=guru", Thing, "$file:$line:$col: defined here as type golang.org/x/tools/internal/lsp/godef/a.Thing")
definition(bStructType, "-emulate=guru", Thing, "$file:$line:$col: defined here as type $$a.Thing")
definition(bMember, "", Member, "$file:$line:$col-$ecol: defined here as field Member string")
definition(bMember, "-emulate=guru", Member, "$file:$line:$col: defined here as field Member string")
definition(bVar, "", Other, "$file:$line:$col-$ecol: defined here as var a.Other a.Thing")
definition(bVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var golang.org/x/tools/internal/lsp/godef/a.Other")
definition(bVar, "-emulate=guru", Other, "$file:$line:$col: defined here as var $$a.Other")
definition(bFunc, "", Things, "$file:$line:$col-$ecol: defined here as func a.Things(val []string) []a.Thing")
definition(bFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func golang.org/x/tools/internal/lsp/godef/a.Things(val []string) []golang.org/x/tools/internal/lsp/godef/a.Thing")
definition(bFunc, "-emulate=guru", Things, "$file:$line:$col: defined here as func $$a.Things")
*/