+++ /dev/null
-// Copyright 2018 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 findcall defines an Analyzer that serves as a trivial
-// example and test of the Analysis API. It reports a diagnostic for
-// every call to a function or method of the name specified by its
-// -name flag. It also exports a fact for each declaration that
-// matches the name, plus a package-level fact if the package contained
-// one or more such declarations.
-package findcall
-
-import (
- "fmt"
- "go/ast"
- "go/types"
-
- "golang.org/x/tools/go/analysis"
-)
-
-const Doc = `find calls to a particular function
-
-The findcall analysis reports calls to functions or methods
-of a particular name.`
-
-var Analyzer = &analysis.Analyzer{
- Name: "findcall",
- Doc: Doc,
- Run: run,
- RunDespiteErrors: true,
- FactTypes: []analysis.Fact{new(foundFact)},
-}
-
-var name string // -name flag
-
-func init() {
- Analyzer.Flags.StringVar(&name, "name", name, "name of the function to find")
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
- for _, f := range pass.Files {
- ast.Inspect(f, func(n ast.Node) bool {
- if call, ok := n.(*ast.CallExpr); ok {
- var id *ast.Ident
- switch fun := call.Fun.(type) {
- case *ast.Ident:
- id = fun
- case *ast.SelectorExpr:
- id = fun.Sel
- }
- if id != nil && !pass.TypesInfo.Types[id].IsType() && id.Name == name {
- pass.Report(analysis.Diagnostic{
- Pos: call.Lparen,
- Message: fmt.Sprintf("call of %s(...)", id.Name),
- SuggestedFixes: []analysis.SuggestedFix{{
- Message: fmt.Sprintf("Add '_TEST_'"),
- TextEdits: []analysis.TextEdit{{
- Pos: call.Lparen,
- End: call.Lparen,
- NewText: []byte("_TEST_"),
- }},
- }},
- })
- }
- }
- return true
- })
- }
-
- // Export a fact for each matching function.
- //
- // These facts are produced only to test the testing
- // infrastructure in the analysistest package.
- // They are not consumed by the findcall Analyzer
- // itself, as would happen in a more realistic example.
- for _, f := range pass.Files {
- for _, decl := range f.Decls {
- if decl, ok := decl.(*ast.FuncDecl); ok && decl.Name.Name == name {
- if obj, ok := pass.TypesInfo.Defs[decl.Name].(*types.Func); ok {
- pass.ExportObjectFact(obj, new(foundFact))
- }
- }
- }
- }
-
- if len(pass.AllObjectFacts()) > 0 {
- pass.ExportPackageFact(new(foundFact))
- }
-
- return nil, nil
-}
-
-// foundFact is a fact associated with functions that match -name.
-// We use it to exercise the fact machinery in tests.
-type foundFact struct{}
-
-func (*foundFact) String() string { return "found" }
-func (*foundFact) AFact() {}