diff --git a/go/analysis/analysistest/analysistest.go b/go/analysis/analysistest/analysistest.go index df79a4419bc..dac75d8a6c7 100644 --- a/go/analysis/analysistest/analysistest.go +++ b/go/analysis/analysistest/analysistest.go @@ -81,23 +81,24 @@ type Testing interface { // Each section in the archive corresponds to a single message. // // A golden file using txtar may look like this: -// -- turn into single negation -- -// package pkg // -// func fn(b1, b2 bool) { -// if !b1 { // want `negating a boolean twice` -// println() -// } -// } +// -- turn into single negation -- +// package pkg // -// -- remove double negation -- -// package pkg +// func fn(b1, b2 bool) { +// if !b1 { // want `negating a boolean twice` +// println() +// } +// } // -// func fn(b1, b2 bool) { -// if b1 { // want `negating a boolean twice` -// println() -// } -// } +// -- remove double negation -- +// package pkg +// +// func fn(b1, b2 bool) { +// if b1 { // want `negating a boolean twice` +// println() +// } +// } func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result { r := Run(t, dir, a, patterns...) diff --git a/go/analysis/doc.go b/go/analysis/doc.go index 94a3bd5d07c..7679bda4359 100644 --- a/go/analysis/doc.go +++ b/go/analysis/doc.go @@ -3,12 +3,10 @@ // license that can be found in the LICENSE file. /* - Package analysis defines the interface between a modular static analysis and an analysis driver program. - -Background +# Background A static analysis is a function that inspects a package of Go code and reports a set of diagnostics (typically mistakes in the code), and @@ -32,8 +30,7 @@ frameworks, code review tools, code-base indexers (such as SourceGraph), documentation viewers (such as godoc), batch pipelines for large code bases, and so on. - -Analyzer +# Analyzer The primary type in the API is Analyzer. An Analyzer statically describes an analysis function: its name, documentation, flags, @@ -115,8 +112,7 @@ Finally, the Run field contains a function to be called by the driver to execute the analysis on a single package. The driver passes it an instance of the Pass type. - -Pass +# Pass A Pass describes a single unit of work: the application of a particular Analyzer to a particular package of Go code. @@ -202,8 +198,7 @@ raw text file, use the following sequence: ... pass.Reportf(tf.LineStart(line), "oops") - -Modular analysis with Facts +# Modular analysis with Facts To improve efficiency and scalability, large programs are routinely built using separate compilation: units of the program are compiled @@ -280,8 +275,7 @@ this fact is built in to the analyzer so that it correctly checks calls to log.Printf even when run in a driver that does not apply it to standard packages. We would like to remove this limitation in future. - -Testing an Analyzer +# Testing an Analyzer The analysistest subpackage provides utilities for testing an Analyzer. In a few lines of code, it is possible to run an analyzer on a package @@ -289,8 +283,7 @@ of testdata files and check that it reported all the expected diagnostics and facts (and no more). Expectations are expressed using "// want ..." comments in the input code. - -Standalone commands +# Standalone commands Analyzers are provided in the form of packages that a driver program is expected to import. The vet command imports a set of several analyzers, @@ -316,6 +309,5 @@ entirety as: A tool that provides multiple analyzers can use multichecker in a similar way, giving it the list of Analyzers. - */ package analysis diff --git a/go/analysis/internal/facts/facts.go b/go/analysis/internal/facts/facts.go index 1fb69c61591..006abab84ef 100644 --- a/go/analysis/internal/facts/facts.go +++ b/go/analysis/internal/facts/facts.go @@ -33,7 +33,6 @@ // accurately ascertain whether pkg.T implements an interface pkg.I // defined as interface{f()}. Exported thus means "described in export // data". -// package facts import ( diff --git a/go/analysis/internal/facts/facts_test.go b/go/analysis/internal/facts/facts_test.go index 13c358230f0..a55e30d7a31 100644 --- a/go/analysis/internal/facts/facts_test.go +++ b/go/analysis/internal/facts/facts_test.go @@ -215,15 +215,15 @@ type pkgLookups struct { // testEncodeDecode tests fact encoding and decoding and simulates how package facts // are passed during analysis. It operates on a group of Go file contents. Then // for each in tests it does the following: -// 1) loads and type checks the package, -// 2) calls facts.Decode to loads the facts exported by its imports, -// 3) exports a myFact Fact for all of package level objects, -// 4) For each lookup for the current package: -// 4.a) lookup the types.Object for an Go source expression in the curent package -// (or confirms one is not expected want=="no object"), -// 4.b) finds a Fact for the object (or confirms one is not expected want=="no fact"), -// 4.c) compares the content of the Fact to want. -// 5) encodes the Facts of the package. +// 1. loads and type checks the package, +// 2. calls facts.Decode to loads the facts exported by its imports, +// 3. exports a myFact Fact for all of package level objects, +// 4. For each lookup for the current package: +// 4.a) lookup the types.Object for an Go source expression in the curent package +// (or confirms one is not expected want=="no object"), +// 4.b) finds a Fact for the object (or confirms one is not expected want=="no fact"), +// 4.c) compares the content of the Fact to want. +// 5. encodes the Facts of the package. // // Note: tests are not independent test cases; order matters (as does a package being // skipped). It changes what Facts can be imported. diff --git a/go/analysis/internal/facts/imports.go b/go/analysis/internal/facts/imports.go index ade0cc6fab4..8a5553e2e9b 100644 --- a/go/analysis/internal/facts/imports.go +++ b/go/analysis/internal/facts/imports.go @@ -20,7 +20,6 @@ import ( // // Packages in the map that are only indirectly imported may be // incomplete (!pkg.Complete()). -// func importMap(imports []*types.Package) map[string]*types.Package { objects := make(map[types.Object]bool) packages := make(map[string]*types.Package) diff --git a/go/analysis/passes/bools/bools.go b/go/analysis/passes/bools/bools.go index 5ae47d8948f..0d8b0bf4f1d 100644 --- a/go/analysis/passes/bools/bools.go +++ b/go/analysis/passes/bools/bools.go @@ -94,8 +94,10 @@ func (op boolOp) commutativeSets(info *types.Info, e *ast.BinaryExpr, seen map[* } // checkRedundant checks for expressions of the form -// e && e -// e || e +// +// e && e +// e || e +// // Exprs must contain only side effect free expressions. func (op boolOp) checkRedundant(pass *analysis.Pass, exprs []ast.Expr) { seen := make(map[string]bool) @@ -110,8 +112,10 @@ func (op boolOp) checkRedundant(pass *analysis.Pass, exprs []ast.Expr) { } // checkSuspect checks for expressions of the form -// x != c1 || x != c2 -// x == c1 && x == c2 +// +// x != c1 || x != c2 +// x == c1 && x == c2 +// // where c1 and c2 are constant expressions. // If c1 and c2 are the same then it's redundant; // if c1 and c2 are different then it's always true or always false. diff --git a/go/analysis/passes/cgocall/cgocall.go b/go/analysis/passes/cgocall/cgocall.go index 5768d0b9b09..b61ee5c3dcc 100644 --- a/go/analysis/passes/cgocall/cgocall.go +++ b/go/analysis/passes/cgocall/cgocall.go @@ -122,8 +122,8 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t // For example, for each raw cgo source file in the original package, // such as this one: // -// package p -// import "C" +// package p +// import "C" // import "fmt" // type T int // const k = 3 @@ -147,9 +147,9 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t // the receiver into the first parameter; // and all functions are renamed to "_". // -// package p -// import . "·this·" // declares T, k, x, y, f, g, T.f -// import "C" +// package p +// import . "·this·" // declares T, k, x, y, f, g, T.f +// import "C" // import "fmt" // const _ = 3 // var _, _ = fmt.Println() @@ -169,7 +169,6 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t // C.f would resolve to "·this·"._C_func_f, for example. But we have // limited ourselves here to preserving function bodies and initializer // expressions since that is all that the cgocall analyzer needs. -// func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*ast.File, info *types.Info, sizes types.Sizes) ([]*ast.File, *types.Info, error) { const thispkg = "·this·" @@ -284,8 +283,9 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a // cgoBaseType tries to look through type conversions involving // unsafe.Pointer to find the real type. It converts: -// unsafe.Pointer(x) => x -// *(*unsafe.Pointer)(unsafe.Pointer(&x)) => x +// +// unsafe.Pointer(x) => x +// *(*unsafe.Pointer)(unsafe.Pointer(&x)) => x func cgoBaseType(info *types.Info, arg ast.Expr) types.Type { switch arg := arg.(type) { case *ast.CallExpr: diff --git a/go/analysis/passes/inspect/inspect.go b/go/analysis/passes/inspect/inspect.go index 4bb652a726c..c1c1127d089 100644 --- a/go/analysis/passes/inspect/inspect.go +++ b/go/analysis/passes/inspect/inspect.go @@ -19,14 +19,13 @@ // Requires: []*analysis.Analyzer{inspect.Analyzer}, // } // -// func run(pass *analysis.Pass) (interface{}, error) { -// inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) -// inspect.Preorder(nil, func(n ast.Node) { -// ... -// }) -// return nil -// } -// +// func run(pass *analysis.Pass) (interface{}, error) { +// inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) +// inspect.Preorder(nil, func(n ast.Node) { +// ... +// }) +// return nil +// } package inspect import ( diff --git a/go/analysis/passes/loopclosure/loopclosure.go b/go/analysis/passes/loopclosure/loopclosure.go index 3ea91574dc8..98de9a9bacd 100644 --- a/go/analysis/passes/loopclosure/loopclosure.go +++ b/go/analysis/passes/loopclosure/loopclosure.go @@ -128,9 +128,9 @@ func run(pass *analysis.Pass) (interface{}, error) { // (but not awaited) in another goroutine as a consequence of the call. // For example, given the g.Go call below, it returns the function literal expression. // -// import "sync/errgroup" -// var g errgroup.Group -// g.Go(func() error { ... }) +// import "sync/errgroup" +// var g errgroup.Group +// g.Go(func() error { ... }) // // Currently only "golang.org/x/sync/errgroup.Group()" is considered. func goInvokes(info *types.Info, call *ast.CallExpr) ast.Expr { diff --git a/go/analysis/passes/pkgfact/pkgfact.go b/go/analysis/passes/pkgfact/pkgfact.go index 2262fc4f13d..f4f5616e564 100644 --- a/go/analysis/passes/pkgfact/pkgfact.go +++ b/go/analysis/passes/pkgfact/pkgfact.go @@ -10,14 +10,14 @@ // Each key/value pair comes from a top-level constant declaration // whose name starts and ends with "_". For example: // -// package p +// package p // -// const _greeting_ = "hello" -// const _audience_ = "world" +// const _greeting_ = "hello" +// const _audience_ = "world" // // the pkgfact analysis output for package p would be: // -// {"greeting": "hello", "audience": "world"}. +// {"greeting": "hello", "audience": "world"}. // // In addition, the analysis reports a diagnostic at each import // showing which key/value pairs it contributes. diff --git a/go/analysis/passes/printf/printf.go b/go/analysis/passes/printf/printf.go index dee37d78ae0..c4ccc95b4fb 100644 --- a/go/analysis/passes/printf/printf.go +++ b/go/analysis/passes/printf/printf.go @@ -342,7 +342,6 @@ func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, k // not do so with gccgo, and nor do some other build systems. // TODO(adonovan): eliminate the redundant facts once this restriction // is lifted. -// var isPrint = stringSet{ "fmt.Errorf": true, "fmt.Fprint": true, @@ -931,9 +930,9 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o // recursiveStringer reports whether the argument e is a potential // recursive call to stringer or is an error, such as t and &t in these examples: // -// func (t *T) String() string { printf("%s", t) } -// func (t T) Error() string { printf("%s", t) } -// func (t T) String() string { printf("%s", &t) } +// func (t *T) String() string { printf("%s", t) } +// func (t T) Error() string { printf("%s", t) } +// func (t T) String() string { printf("%s", &t) } func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) { typ := pass.TypesInfo.Types[e].Type diff --git a/go/analysis/passes/shadow/shadow.go b/go/analysis/passes/shadow/shadow.go index b160dcf5b94..a19cecd14b6 100644 --- a/go/analysis/passes/shadow/shadow.go +++ b/go/analysis/passes/shadow/shadow.go @@ -120,7 +120,6 @@ func run(pass *analysis.Pass) (interface{}, error) { // the block, we should complain about it but don't. // - A variable declared inside a function literal can falsely be identified // as shadowing a variable in the outer function. -// type span struct { min token.Pos max token.Pos diff --git a/go/analysis/passes/tests/tests.go b/go/analysis/passes/tests/tests.go index ffa5205dd77..56b20ebd519 100644 --- a/go/analysis/passes/tests/tests.go +++ b/go/analysis/passes/tests/tests.go @@ -84,7 +84,7 @@ func run(pass *analysis.Pass) (interface{}, error) { return nil, nil } -// Checks the contents of a fuzz function. +// checkFuzz checks the contents of a fuzz function. func checkFuzz(pass *analysis.Pass, fn *ast.FuncDecl) { params := checkFuzzCall(pass, fn) if params != nil { @@ -92,15 +92,17 @@ func checkFuzz(pass *analysis.Pass, fn *ast.FuncDecl) { } } -// Check the arguments of f.Fuzz() calls : -// 1. f.Fuzz() should call a function and it should be of type (*testing.F).Fuzz(). -// 2. The called function in f.Fuzz(func(){}) should not return result. -// 3. First argument of func() should be of type *testing.T -// 4. Second argument onwards should be of type []byte, string, bool, byte, -// rune, float32, float64, int, int8, int16, int32, int64, uint, uint8, uint16, -// uint32, uint64 -// 5. func() must not call any *F methods, e.g. (*F).Log, (*F).Error, (*F).Skip -// The only *F methods that are allowed in the (*F).Fuzz function are (*F).Failed and (*F).Name. +// checkFuzzCall checks the arguments of f.Fuzz() calls: +// +// 1. f.Fuzz() should call a function and it should be of type (*testing.F).Fuzz(). +// 2. The called function in f.Fuzz(func(){}) should not return result. +// 3. First argument of func() should be of type *testing.T +// 4. Second argument onwards should be of type []byte, string, bool, byte, +// rune, float32, float64, int, int8, int16, int32, int64, uint, uint8, uint16, +// uint32, uint64 +// 5. func() must not call any *F methods, e.g. (*F).Log, (*F).Error, (*F).Skip +// The only *F methods that are allowed in the (*F).Fuzz function are (*F).Failed and (*F).Name. +// // Returns the list of parameters to the fuzz function, if they are valid fuzz parameters. func checkFuzzCall(pass *analysis.Pass, fn *ast.FuncDecl) (params *types.Tuple) { ast.Inspect(fn, func(n ast.Node) bool { @@ -160,7 +162,7 @@ func checkFuzzCall(pass *analysis.Pass, fn *ast.FuncDecl) (params *types.Tuple) return params } -// Check that the arguments of f.Add() calls have the same number and type of arguments as +// checkAddCalls checks that the arguments of f.Add calls have the same number and type of arguments as // the signature of the function passed to (*testing.F).Fuzz func checkAddCalls(pass *analysis.Pass, fn *ast.FuncDecl, params *types.Tuple) { ast.Inspect(fn, func(n ast.Node) bool { diff --git a/go/analysis/passes/unusedwrite/unusedwrite.go b/go/analysis/passes/unusedwrite/unusedwrite.go index 37a0e784bca..4aad083891f 100644 --- a/go/analysis/passes/unusedwrite/unusedwrite.go +++ b/go/analysis/passes/unusedwrite/unusedwrite.go @@ -41,7 +41,7 @@ Another example is about non-pointer receiver: ` // Analyzer reports instances of writes to struct fields and arrays -//that are never read. +// that are never read. var Analyzer = &analysis.Analyzer{ Name: "unusedwrite", Doc: Doc, diff --git a/go/analysis/singlechecker/singlechecker.go b/go/analysis/singlechecker/singlechecker.go index 28530777be6..91044ca0858 100644 --- a/go/analysis/singlechecker/singlechecker.go +++ b/go/analysis/singlechecker/singlechecker.go @@ -11,16 +11,15 @@ // all that is needed to define a standalone tool is a file, // example.org/findbadness/cmd/findbadness/main.go, containing: // -// // The findbadness command runs an analysis. -// package main +// // The findbadness command runs an analysis. +// package main // -// import ( -// "example.org/findbadness" -// "golang.org/x/tools/go/analysis/singlechecker" -// ) -// -// func main() { singlechecker.Main(findbadness.Analyzer) } +// import ( +// "example.org/findbadness" +// "golang.org/x/tools/go/analysis/singlechecker" +// ) // +// func main() { singlechecker.Main(findbadness.Analyzer) } package singlechecker import ( diff --git a/go/analysis/unitchecker/main.go b/go/analysis/unitchecker/main.go index 23acb7ed02a..a054a2dcee2 100644 --- a/go/analysis/unitchecker/main.go +++ b/go/analysis/unitchecker/main.go @@ -10,8 +10,8 @@ // It serves as a model for the behavior of the cmd/vet tool in $GOROOT. // Being based on the unitchecker driver, it must be run by go vet: // -// $ go build -o unitchecker main.go -// $ go vet -vettool=unitchecker my/project/... +// $ go build -o unitchecker main.go +// $ go vet -vettool=unitchecker my/project/... // // For a checker also capable of running standalone, use multichecker. package main diff --git a/go/analysis/unitchecker/unitchecker.go b/go/analysis/unitchecker/unitchecker.go index b539866ddd4..9827b57f529 100644 --- a/go/analysis/unitchecker/unitchecker.go +++ b/go/analysis/unitchecker/unitchecker.go @@ -6,13 +6,13 @@ // driver that analyzes a single compilation unit during a build. // It is invoked by a build system such as "go vet": // -// $ go vet -vettool=$(which vet) +// $ go vet -vettool=$(which vet) // // It supports the following command-line protocol: // -// -V=full describe executable (to the build tool) -// -flags describe flags (to the build tool) -// foo.cfg description of compilation unit (from the build tool) +// -V=full describe executable (to the build tool) +// -flags describe flags (to the build tool) +// foo.cfg description of compilation unit (from the build tool) // // This package does not depend on go/packages. // If you need a standalone tool, use multichecker, @@ -79,11 +79,10 @@ type Config struct { // // The protocol required by 'go vet -vettool=...' is that the tool must support: // -// -flags describe flags in JSON -// -V=full describe executable for build caching -// foo.cfg perform separate modular analyze on the single -// unit described by a JSON config file foo.cfg. -// +// -flags describe flags in JSON +// -V=full describe executable for build caching +// foo.cfg perform separate modular analyze on the single +// unit described by a JSON config file foo.cfg. func Main(analyzers ...*analysis.Analyzer) { progname := filepath.Base(os.Args[0]) log.SetFlags(0)