diff options
Diffstat (limited to 'internal/lsp/source/completion/fuzz.go')
-rw-r--r-- | internal/lsp/source/completion/fuzz.go | 142 |
1 files changed, 0 insertions, 142 deletions
diff --git a/internal/lsp/source/completion/fuzz.go b/internal/lsp/source/completion/fuzz.go deleted file mode 100644 index 92349ab93..000000000 --- a/internal/lsp/source/completion/fuzz.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package completion - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" - - "golang.org/x/tools/internal/lsp/protocol" -) - -// golang/go#51089 -// *testing.F deserves special treatment as member use is constrained: -// The arguments to f.Fuzz are determined by the arguments to a previous f.Add -// Inside f.Fuzz only f.Failed and f.Name are allowed. -// PJW: are there other packages where we can deduce usage constraints? - -// if we find fuzz completions, then return true, as those are the only completions to offer -func (c *completer) fuzz(typ types.Type, mset *types.MethodSet, imp *importInfo, cb func(candidate), fset *token.FileSet) bool { - // 1. inside f.Fuzz? (only f.Failed and f.Name) - // 2. possible completing f.Fuzz? - // [Ident,SelectorExpr,Callexpr,ExprStmt,BlockiStmt,FuncDecl(Fuzz...)] - // 3. before f.Fuzz, same (for 2., offer choice when looking at an F) - - // does the path contain FuncLit as arg to f.Fuzz CallExpr? - inside := false -Loop: - for i, n := range c.path { - switch v := n.(type) { - case *ast.CallExpr: - if len(v.Args) != 1 { - continue Loop - } - if _, ok := v.Args[0].(*ast.FuncLit); !ok { - continue - } - if s, ok := v.Fun.(*ast.SelectorExpr); !ok || s.Sel.Name != "Fuzz" { - continue - } - if i > 2 { // avoid t.Fuzz itself in tests - inside = true - break Loop - } - } - } - if inside { - for i := 0; i < mset.Len(); i++ { - o := mset.At(i).Obj() - if o.Name() == "Failed" || o.Name() == "Name" { - cb(candidate{ - obj: o, - score: stdScore, - imp: imp, - addressable: true, - }) - } - } - return true - } - // if it could be t.Fuzz, look for the preceding t.Add - id, ok := c.path[0].(*ast.Ident) - if ok && strings.HasPrefix("Fuzz", id.Name) { - var add *ast.CallExpr - f := func(n ast.Node) bool { - if n == nil { - return true - } - call, ok := n.(*ast.CallExpr) - if !ok { - return true - } - s, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - return true - } - if s.Sel.Name != "Add" { - return true - } - // Sel.X should be of type *testing.F - got := c.pkg.GetTypesInfo().Types[s.X] - if got.Type.String() == "*testing.F" { - add = call - } - return false // because we're done... - } - // look at the enclosing FuzzFoo functions - if len(c.path) < 2 { - return false - } - n := c.path[len(c.path)-2] - if _, ok := n.(*ast.FuncDecl); !ok { - // the path should start with ast.File, ast.FuncDecl, ... - // but it didn't, so give up - return false - } - ast.Inspect(n, f) - if add == nil { - // looks like f.Fuzz without a preceding f.Add. - // let the regular completion handle it. - return false - } - - lbl := "Fuzz(func(t *testing.T" - for i, a := range add.Args { - info := c.pkg.GetTypesInfo().TypeOf(a) - if info == nil { - return false // How could this happen, but better safe than panic. - } - lbl += fmt.Sprintf(", %c %s", 'a'+i, info) - } - lbl += ")" - xx := CompletionItem{ - Label: lbl, - InsertText: lbl, - Kind: protocol.FunctionCompletion, - Depth: 0, - Score: 10, // pretty confident the user should see this - Documentation: "argument types from f.Add", - obj: nil, - } - c.items = append(c.items, xx) - for i := 0; i < mset.Len(); i++ { - o := mset.At(i).Obj() - if o.Name() != "Fuzz" { - cb(candidate{ - obj: o, - score: stdScore, - imp: imp, - addressable: true, - }) - } - } - return true // done - } - // let the standard processing take care of it instead - return false -} |