aboutsummaryrefslogtreecommitdiff
path: root/internal/lsp/source/completion/fuzz.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lsp/source/completion/fuzz.go')
-rw-r--r--internal/lsp/source/completion/fuzz.go142
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
-}