golang.org/x/tools/gopls@v0.15.3/internal/analysis/noresultvalues/noresultvalues.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package noresultvalues 6 7 import ( 8 "bytes" 9 "go/ast" 10 "go/format" 11 "strings" 12 13 _ "embed" 14 15 "golang.org/x/tools/go/analysis" 16 "golang.org/x/tools/go/analysis/passes/inspect" 17 "golang.org/x/tools/go/ast/inspector" 18 "golang.org/x/tools/internal/analysisinternal" 19 ) 20 21 //go:embed doc.go 22 var doc string 23 24 var Analyzer = &analysis.Analyzer{ 25 Name: "noresultvalues", 26 Doc: analysisinternal.MustExtractDoc(doc, "noresultvalues"), 27 Requires: []*analysis.Analyzer{inspect.Analyzer}, 28 Run: run, 29 RunDespiteErrors: true, 30 URL: "https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/noresultvars", 31 } 32 33 func run(pass *analysis.Pass) (interface{}, error) { 34 inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) 35 if len(pass.TypeErrors) == 0 { 36 return nil, nil 37 } 38 39 nodeFilter := []ast.Node{(*ast.ReturnStmt)(nil)} 40 inspect.Preorder(nodeFilter, func(n ast.Node) { 41 retStmt, _ := n.(*ast.ReturnStmt) 42 43 var file *ast.File 44 for _, f := range pass.Files { 45 if f.Pos() <= retStmt.Pos() && retStmt.Pos() < f.End() { 46 file = f 47 break 48 } 49 } 50 if file == nil { 51 return 52 } 53 54 for _, err := range pass.TypeErrors { 55 if !FixesError(err.Msg) { 56 continue 57 } 58 if retStmt.Pos() >= err.Pos || err.Pos >= retStmt.End() { 59 continue 60 } 61 var buf bytes.Buffer 62 if err := format.Node(&buf, pass.Fset, file); err != nil { 63 continue 64 } 65 pass.Report(analysis.Diagnostic{ 66 Pos: err.Pos, 67 End: analysisinternal.TypeErrorEndPos(pass.Fset, buf.Bytes(), err.Pos), 68 Message: err.Msg, 69 SuggestedFixes: []analysis.SuggestedFix{{ 70 Message: "Delete return values", 71 TextEdits: []analysis.TextEdit{{ 72 Pos: retStmt.Pos(), 73 End: retStmt.End(), 74 NewText: []byte("return"), 75 }}, 76 }}, 77 }) 78 } 79 }) 80 return nil, nil 81 } 82 83 func FixesError(msg string) bool { 84 return msg == "no result values expected" || 85 strings.HasPrefix(msg, "too many return values") && strings.Contains(msg, "want ()") 86 }