From 1b6223219411a7d03bb5ddd4eddff18c0297f8b9 Mon Sep 17 00:00:00 2001 From: "Iskander (Alex) Sharipov" Date: Thu, 14 Oct 2021 18:21:06 +0300 Subject: [PATCH] analyzer/testdata: use `\Q` regexp quoting everywhere (#279) In analysis test we're using `want` directive to match warnings. I personally thing that 99% of time we need a string matching, not a regexp matching. So this test checks that we do `\Q` escaping everywhere, making our patterns matching string "as is"; so you don't have to escape `(` and `)` in the patterns. --- analyzer/analyzer_test.go | 42 +++++ analyzer/testdata/src/comments/target.go | 2 +- analyzer/testdata/src/comments/target_foo.go | 2 +- analyzer/testdata/src/dgryski/learngo.go | 2 +- analyzer/testdata/src/extra/file.go | 26 +-- analyzer/testdata/src/filtertest/f1.go | 148 +++++++++--------- analyzer/testdata/src/filtertest/foo_file1.go | 2 +- analyzer/testdata/src/filtertest/foo_file2.go | 2 +- .../src/filtertest/imports_filepath.go | 4 +- analyzer/testdata/src/filtertest/linetest4.go | 2 +- analyzer/testdata/src/filtertest/rules.go | 84 +++++----- analyzer/testdata/src/gocritic/f1.go | 60 +++---- analyzer/testdata/src/golint/file.go | 6 +- analyzer/testdata/src/matching/file.go | 10 +- .../testdata/src/namedtype/nested/example.go | 12 +- .../testdata/src/namedtype/nested/example2.go | 2 +- analyzer/testdata/src/regression/issue68.go | 4 +- analyzer/testdata/src/revive/file.go | 12 +- analyzer/testdata/src/suggest/file.go | 2 +- analyzer/testdata/src/testvendored/file.go | 8 +- 20 files changed, 237 insertions(+), 195 deletions(-) diff --git a/analyzer/analyzer_test.go b/analyzer/analyzer_test.go index e327fa81..86c8b244 100644 --- a/analyzer/analyzer_test.go +++ b/analyzer/analyzer_test.go @@ -4,10 +4,13 @@ import ( "bytes" "fmt" "go/token" + "io/fs" "io/ioutil" "os" "os/exec" "path/filepath" + "regexp" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -42,6 +45,45 @@ var tests = []struct { {name: "goversion", flags: map[string]string{"go": "1.16"}}, } +func TestDirectiveComments(t *testing.T) { + testdata := analysistest.TestData() + badDirectiveRe := regexp.MustCompile("// want `[^\\\\][^Q].*") + err := filepath.WalkDir(testdata, func(filename string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + return nil + } + if !strings.HasSuffix(filename, ".go") { + return nil + } + data, err := os.ReadFile(filename) + if err != nil { + return err + } + lines := bytes.Split(data, []byte("\n")) + for i, l := range lines { + m := badDirectiveRe.Find(l) + if m == nil { + continue + } + if bytes.HasPrefix(m, []byte("// want `true")) { + continue + } + if bytes.HasPrefix(m, []byte("// want `false")) { + continue + } + relName := strings.TrimPrefix(filename, filepath.Join(testdata, "src")+"/") + t.Errorf("%s:%d: escape 'want' text with \\Q in %s", relName, i+1, m) + } + return nil + }) + if err != nil { + t.Fatal(err) + } +} + func TestAnalyzer(t *testing.T) { analyzer.ForceNewEngine = true for i := range tests { diff --git a/analyzer/testdata/src/comments/target.go b/analyzer/testdata/src/comments/target.go index 056e540d..c9c62896 100644 --- a/analyzer/testdata/src/comments/target.go +++ b/analyzer/testdata/src/comments/target.go @@ -18,7 +18,7 @@ func f() { //go:noinline //go:generate foo bar - //nolint:gocritic // want `hey, this is kinda upsetting` + //nolint:gocritic // want `\Qhey, this is kinda upsetting` // This is a begining // want `\Q"begining" may contain a typo` // Of a bizzare text with typos. // want `\Q"bizzare" may contain a typo` diff --git a/analyzer/testdata/src/comments/target_foo.go b/analyzer/testdata/src/comments/target_foo.go index d49a8ae7..38758143 100644 --- a/analyzer/testdata/src/comments/target_foo.go +++ b/analyzer/testdata/src/comments/target_foo.go @@ -1,3 +1,3 @@ package comments -//go:embed data.txt // want `don't use go:embed in _foo files` +//go:embed data.txt // want `\Qdon't use go:embed in _foo files` diff --git a/analyzer/testdata/src/dgryski/learngo.go b/analyzer/testdata/src/dgryski/learngo.go index 8f132381..5537dacd 100644 --- a/analyzer/testdata/src/dgryski/learngo.go +++ b/analyzer/testdata/src/dgryski/learngo.go @@ -179,7 +179,7 @@ func learnFlowControl() { } // Use switch in preference to chained if statements. x := 42.0 - switch x { // want `floating point as switch expression` + switch x { // want `\Qfloating point as switch expression` case 0: case 1, 2: // Can have multiple matches on one case case 42: diff --git a/analyzer/testdata/src/extra/file.go b/analyzer/testdata/src/extra/file.go index b4b4b702..b977437e 100644 --- a/analyzer/testdata/src/extra/file.go +++ b/analyzer/testdata/src/extra/file.go @@ -67,7 +67,7 @@ func testFormatBool() { func testBlankAssign() { x := foo() - _ = x // want `please remove the assignment to _` + _ = x // want `\Qplease remove the assignment to _` // This is OK, could be for side-effects. _ = foo() @@ -92,10 +92,10 @@ func nilErrCheck() { } func unparen(x, y int) { - if (x == 0) || (y == 0) { // want `rewrite as 'x == 0 || y == 0'` + if (x == 0) || (y == 0) { // want `\Qrewrite as 'x == 0 || y == 0'` } - if (x != 5) && (y == 5) { // want `rewrite as 'x != 5 && y == 5'` + if (x != 5) && (y == 5) { // want `\Qrewrite as 'x != 5 && y == 5'` } } @@ -148,7 +148,7 @@ func makeExpr() { func chanRange() int { ch := make(chan int) - for { // want `can use for range over ch` + for { // want `\Qcan use for range over ch` select { case c := <-ch: return c @@ -184,7 +184,7 @@ func argOrder() { func stringsReplace() { var s string - _ = strings.Replace(s, " ", " ", -1) // want `replace 'old' and 'new' parameters are identical` + _ = strings.Replace(s, " ", " ", -1) // want `\Qreplace 'old' and 'new' parameters are identical` } func stringsRepeat() { @@ -209,11 +209,11 @@ func stringsRepeat() { func stringsCompare() { var s1, s2 string - _ = strings.Compare(s1, s2) == 0 // want `suggestion: s1 == s2` - _ = strings.Compare(s1, s2) < 0 // want `suggestion: s1 < s2` - _ = strings.Compare(s1, s2) == -1 // want `suggestion: s1 < s2` - _ = strings.Compare(s1, s2) > 0 // want `suggestion: s1 > s2` - _ = strings.Compare(s1, s2) == 1 // want `suggestion: s1 > s2` + _ = strings.Compare(s1, s2) == 0 // want `\Qsuggestion: s1 == s2` + _ = strings.Compare(s1, s2) < 0 // want `\Qsuggestion: s1 < s2` + _ = strings.Compare(s1, s2) == -1 // want `\Qsuggestion: s1 < s2` + _ = strings.Compare(s1, s2) > 0 // want `\Qsuggestion: s1 > s2` + _ = strings.Compare(s1, s2) == 1 // want `\Qsuggestion: s1 > s2` if s1 == s2 { } @@ -298,7 +298,7 @@ func testCtx(ctx context.Context) error { return nil } -type errDontLog error // want `error as underlying type is probably a mistake` +type errDontLog error // want `\Qerror as underlying type is probably a mistake` var ( // want `\Qempty var() block` // Empty decl... @@ -436,8 +436,8 @@ func redundantLenCheck(xs []int, v int) { } func emptyError() { - _ = errors.New("") // want `empty error` - _ = errors.New(``) // want `empty error` + _ = errors.New("") // want `\Qempty error` + _ = errors.New(``) // want `\Qempty error` } func contextWithValue(ctx context.Context) { diff --git a/analyzer/testdata/src/filtertest/f1.go b/analyzer/testdata/src/filtertest/f1.go index 38cace7a..bfed4339 100644 --- a/analyzer/testdata/src/filtertest/f1.go +++ b/analyzer/testdata/src/filtertest/f1.go @@ -34,7 +34,7 @@ func (v vector2D) String() string { func _() { fileTest("with foo prefix") - fileTest("f1.go") // want `YES` + fileTest("f1.go") // want `true` } func detectObject() { @@ -72,23 +72,23 @@ func detectObject() { func convertibleTo() { type myInt2Array [2]int - typeTest([2]int{}, "convertible to ([2]int)") // want `YES` - typeTest(myInt2Array{}, "convertible to ([2]int)") // want `YES` + typeTest([2]int{}, "convertible to ([2]int)") // want `true` + typeTest(myInt2Array{}, "convertible to ([2]int)") // want `true` typeTest([3]int{}, "convertible to ([2]int)") type myIntSlice2 [][]int - typeTest([][]int{{1}}, "convertible to [][]int") // want `YES` - typeTest(myIntSlice2(nil), "convertible to [][]int") // want `YES` + typeTest([][]int{{1}}, "convertible to [][]int") // want `true` + typeTest(myIntSlice2(nil), "convertible to [][]int") // want `true` typeTest([]int{}, "convertible to [][]int") } func assignableTo() { - typeTest(map[*string]error{}, "assignable to map[*string]error") // want `YES` + typeTest(map[*string]error{}, "assignable to map[*string]error") // want `true` typeTest(map[*string]int{}, "assignable to map[*string]error") - typeTest(0, "assignable to interface{}") // want `YES` - typeTest(5.6, "assignable to interface{}") // want `YES` - typeTest("", "assignable to interface{}") // want `YES` + typeTest(0, "assignable to interface{}") // want `true` + typeTest(5.6, "assignable to interface{}") // want `true` + typeTest("", "assignable to interface{}") // want `true` } func detectValue() { @@ -107,14 +107,14 @@ func detectType() { var s fmt.Stringer typeTest(s, "is interface") - typeTest(interface{}(nil), "is interface") // want `YES` + typeTest(interface{}(nil), "is interface") // want `true` typeTest(implementsAll{}, "is interface") typeTest(&implementsAll{}, "is interface") typeTest(4, "is interface") typeTest("", "is interface") - typeTest(s, "underlying is interface") // want `YES` - typeTest(interface{}(nil), "underlying is interface") // want `YES` + typeTest(s, "underlying is interface") // want `true` + typeTest(interface{}(nil), "underlying is interface") // want `true` typeTest(implementsAll{}, "underlying is interface") typeTest(&implementsAll{}, "underlying is interface") typeTest(4, "underlying is interface") @@ -132,10 +132,10 @@ func detectType() { var bar withNamedTime type indirectFoo1 withNamedTime type indirectFoo2 indirectFoo1 - typeTest(withNamedTime{}, "contains time.Time") // want `YES` - typeTest(foo, "contains time.Time") // want `YES` - typeTest(bar, "contains time.Time") // want `YES` - typeTest(indirectFoo2{}, "contains time.Time") // want `YES` + typeTest(withNamedTime{}, "contains time.Time") // want `true` + typeTest(foo, "contains time.Time") // want `true` + typeTest(bar, "contains time.Time") // want `true` + typeTest(indirectFoo2{}, "contains time.Time") // want `true` } { @@ -147,9 +147,9 @@ func detectType() { x time.Time } var bar timeFirst - typeTest(timeFirst{}, "starts with time.Time") // want `YES` - typeTest(foo, "starts with time.Time") // want `YES` - typeTest(bar, "starts with time.Time") // want `YES` + typeTest(timeFirst{}, "starts with time.Time") // want `true` + typeTest(foo, "starts with time.Time") // want `true` + typeTest(bar, "starts with time.Time") // want `true` } { @@ -162,12 +162,12 @@ func detectType() { y float32 } var bar intPair - typeTest(struct { // want `YES` + typeTest(struct { // want `true` _ string _ string }{}, "non-underlying type test; T + T") typeTest(intPair{}, "non-underlying type test; T + T") // type is Named, not struct - typeTest(foo, "non-underlying type test; T + T") // want `YES` + typeTest(foo, "non-underlying type test; T + T") // want `true` typeTest(bar, "non-underlying type test; T + T") // type is Named, not struct } @@ -175,8 +175,8 @@ func detectType() { var ii []int var s1, s2 string var ss []string - typeTest(s1 + s2) // want `concat` - typeTest(i1 + i2) // want `addition` + typeTest(s1 + s2) // want `\Qconcat` + typeTest(i1 + i2) // want `\Qaddition` typeTest(s1 > s2) // want `\Qs1 !is(int)` typeTest(i1 > i2) // want `\Qi1 !is(string) && pure` typeTest(random() > i2) @@ -186,23 +186,23 @@ func detectType() { typeTest("2 type filters", s1) typeTest("2 type filters", ii) // want `\Qii !is(string) && !is(int)` - typeTest(implementsAll{}, "implements io.Reader") // want `YES` + typeTest(implementsAll{}, "implements io.Reader") // want `true` typeTest(i1, "implements io.Reader") typeTest(ss, "implements io.Reader") - typeTest(implementsAll{}, "implements foolib.Stringer") // want `YES` + typeTest(implementsAll{}, "implements foolib.Stringer") // want `true` typeTest(i1, "implements foolib.Stringer") typeTest(ss, "implements foolib.Stringer") typeTest(implementsAll{}, "implements error") - typeTest(&implementsAll{}, "implements error") // want `YES` + typeTest(&implementsAll{}, "implements error") // want `true` typeTest(i1, "implements error") - typeTest(error(nil), "implements error") // want `YES` - typeTest(errors.New("example"), "implements error") // want `YES` + typeTest(error(nil), "implements error") // want `true` + typeTest(errors.New("example"), "implements error") // want `true` typeTest(implementsAllNewtype{}, "implements error") typeTest(&implementsAllNewtype{}, "implements error") typeTest(embedImplementsAll{}, "implements error") - typeTest(&embedImplementsAll{}, "implements error") // want `YES` - typeTest(embedImplementsAllPtr{}, "implements error") // want `YES` - typeTest(&embedImplementsAllPtr{}, "implements error") // want `YES` + typeTest(&embedImplementsAll{}, "implements error") // want `true` + typeTest(embedImplementsAllPtr{}, "implements error") // want `true` + typeTest(&embedImplementsAllPtr{}, "implements error") // want `true` typeTest(&implementsAll{}, "variadic implements error") // want `true` typeTest(&implementsAll{}, error(nil), "variadic implements error") // want `true` @@ -220,24 +220,24 @@ func detectType() { typeTest(embedImplementsAll{}, 1, "variadic implements error") // want `false` typeTest(embedImplementsAll{}, error(nil), "variadic implements error") // want `false` - typeTest([100]byte{}, "size>=100") // want `YES` - typeTest([105]byte{}, "size>=100") // want `YES` + typeTest([100]byte{}, "size>=100") // want `true` + typeTest([105]byte{}, "size>=100") // want `true` typeTest([10]byte{}, "size>=100") - typeTest([100]byte{}, "size<=100") // want `YES` + typeTest([100]byte{}, "size<=100") // want `true` typeTest([105]byte{}, "size<=100") - typeTest([10]byte{}, "size<=100") // want `YES` + typeTest([10]byte{}, "size<=100") // want `true` typeTest([100]byte{}, "size>100") - typeTest([105]byte{}, "size>100") // want `YES` + typeTest([105]byte{}, "size>100") // want `true` typeTest([10]byte{}, "size>100") typeTest([100]byte{}, "size<100") typeTest([105]byte{}, "size<100") - typeTest([10]byte{}, "size<100") // want `YES` - typeTest([100]byte{}, "size==100") // want `YES` + typeTest([10]byte{}, "size<100") // want `true` + typeTest([100]byte{}, "size==100") // want `true` typeTest([105]byte{}, "size==100") typeTest([10]byte{}, "size==100") typeTest([100]byte{}, "size!=100") - typeTest([105]byte{}, "size!=100") // want `YES` - typeTest([10]byte{}, "size!=100") // want `YES` + typeTest([105]byte{}, "size!=100") // want `true` + typeTest([10]byte{}, "size!=100") // want `true` typeTest("variadic size==4") // want `true` typeTest([4]byte{}, "variadic size==4") // want `true` @@ -249,26 +249,26 @@ func detectType() { var time1, time2 time.Time var err error - typeTest(time1 == time2, "time==time") // want `YES` + typeTest(time1 == time2, "time==time") // want `true` typeTest(err == nil, "time==time") typeTest(nil == err, "time==time") - typeTest(time1 != time2, "time!=time") // want `YES` + typeTest(time1 != time2, "time!=time") // want `true` typeTest(err != nil, "time!=time") typeTest(nil != err, "time!=time") intFunc := func() int { return 10 } intToIntFunc := func(x int) int { return x } - typeTest(intFunc(), "func() int") // want `YES` - typeTest(func() int { return 0 }(), "func() int") // want `YES` + typeTest(intFunc(), "func() int") // want `true` + typeTest(func() int { return 0 }(), "func() int") // want `true` typeTest(func() string { return "" }(), "func() int") typeTest(intToIntFunc(1), "func() int") - typeTest(intToIntFunc(2), "func(int) int") // want `YES` + typeTest(intToIntFunc(2), "func(int) int") // want `true` typeTest(intToIntFunc, "func(int) int") typeTest(intFunc, "func(int) int") var v implementsAll - typeTest(v.String(), "func() string") // want `YES` + typeTest(v.String(), "func() string") // want `true` typeTest(implementsAll.String(v), "func() string") typeTest(implementsAll.String, "func() string") @@ -404,28 +404,28 @@ func detectPure(x int, xs []int) { } func detectText(foo, bar int) { - textTest(foo, "text=foo") // want `YES` + textTest(foo, "text=foo") // want `true` textTest(bar, "text=foo") - textTest("foo", "text='foo'") // want `YES` + textTest("foo", "text='foo'") // want `true` textTest("bar", "text='foo'") - textTest("bar", "text!='foo'") // want `YES` + textTest("bar", "text!='foo'") // want `true` textTest("foo", "text!='foo'") - textTest(32, "matches d+") // want `YES` + textTest(32, "matches d+") // want `true` textTest(0x32, "matches d+") textTest("foo", "matches d+") - textTest(1, "doesn't match [A-Z]") // want `YES` + textTest(1, "doesn't match [A-Z]") // want `true` textTest("ABC", "doesn't match [A-Z]") - textTest("", "root text test") // want `YES` + textTest("", "root text test") // want `true` } func detectParensFilter() { var err error - parensFilterTest(err, "type is error") // want `YES` + parensFilterTest(err, "type is error") // want `true` } func fileFilters1() { @@ -435,11 +435,11 @@ func fileFilters1() { } func detectLine() { - lineTest(1, 2, "same line") // want `YES` + lineTest(1, 2, "same line") // want `true` lineTest(1, 2, "same line") - lineTest( // want `YES` + lineTest( // want `true` 1, 2, "different line", @@ -461,34 +461,34 @@ func detectNode() { f() f() - nodeTest("123", "Expr") // want `YES` - nodeTest(`123`, "Expr") // want `YES` - nodeTest(12, "Expr") // want `YES` - nodeTest(1.56, "Expr") // want `YES` - nodeTest(1+2, "Expr") // want `YES` - nodeTest(i, "Expr") // want `YES` - nodeTest(s, "Expr") // want `YES` - - nodeTest("123", "BasicLit") // want `YES` - nodeTest(`123`, "BasicLit") // want `YES` - nodeTest(12, "BasicLit") // want `YES` - nodeTest(1.56, "BasicLit") // want `YES` + nodeTest("123", "Expr") // want `true` + nodeTest(`123`, "Expr") // want `true` + nodeTest(12, "Expr") // want `true` + nodeTest(1.56, "Expr") // want `true` + nodeTest(1+2, "Expr") // want `true` + nodeTest(i, "Expr") // want `true` + nodeTest(s, "Expr") // want `true` + + nodeTest("123", "BasicLit") // want `true` + nodeTest(`123`, "BasicLit") // want `true` + nodeTest(12, "BasicLit") // want `true` + nodeTest(1.56, "BasicLit") // want `true` nodeTest(1+2, "BasicLit") nodeTest(i, "BasicLit") nodeTest(s, "BasicLit") nodeTest("123", "Ident") nodeTest(12, "Ident") - nodeTest(i, "Ident") // want `YES` - nodeTest(s, "Ident") // want `YES` + nodeTest(i, "Ident") // want `true` + nodeTest(s, "Ident") // want `true` - nodeTest("42", "!Ident") // want `YES` - nodeTest(12, "!Ident") // want `YES` - nodeTest(s[0], "!Ident") // want `YES` + nodeTest("42", "!Ident") // want `true` + nodeTest(12, "!Ident") // want `true` + nodeTest(s[0], "!Ident") // want `true` nodeTest(i, "!Ident") nodeTest(s, "!Ident") - nodeTest(s[0], "IndexExpr") // want `YES` - nodeTest(rows[0][5], "IndexExpr") // want `YES` + nodeTest(s[0], "IndexExpr") // want `true` + nodeTest(rows[0][5], "IndexExpr") // want `true` nodeTest("42", "IndexExpr") } diff --git a/analyzer/testdata/src/filtertest/foo_file1.go b/analyzer/testdata/src/filtertest/foo_file1.go index 79f962f1..be5784d0 100644 --- a/analyzer/testdata/src/filtertest/foo_file1.go +++ b/analyzer/testdata/src/filtertest/foo_file1.go @@ -1,5 +1,5 @@ package filtertest func _() { - fileTest("with foo prefix") // want `YES` + fileTest("with foo prefix") // want `true` } diff --git a/analyzer/testdata/src/filtertest/foo_file2.go b/analyzer/testdata/src/filtertest/foo_file2.go index 79f962f1..be5784d0 100644 --- a/analyzer/testdata/src/filtertest/foo_file2.go +++ b/analyzer/testdata/src/filtertest/foo_file2.go @@ -1,5 +1,5 @@ package filtertest func _() { - fileTest("with foo prefix") // want `YES` + fileTest("with foo prefix") // want `true` } diff --git a/analyzer/testdata/src/filtertest/imports_filepath.go b/analyzer/testdata/src/filtertest/imports_filepath.go index af65a7b1..b8fc8f49 100644 --- a/analyzer/testdata/src/filtertest/imports_filepath.go +++ b/analyzer/testdata/src/filtertest/imports_filepath.go @@ -6,9 +6,9 @@ import ( ) func fileFilters2() { - importsTest(os.PathSeparator, "path/filepath") // want `YES` + importsTest(os.PathSeparator, "path/filepath") // want `true` importsTest(filepath.Separator, "path/filepath") - importsTest(os.PathListSeparator, "path/filepath") // want `YES` + importsTest(os.PathListSeparator, "path/filepath") // want `true` importsTest(filepath.ListSeparator, "path/filepath") } diff --git a/analyzer/testdata/src/filtertest/linetest4.go b/analyzer/testdata/src/filtertest/linetest4.go index 2553b3ed..22456e71 100644 --- a/analyzer/testdata/src/filtertest/linetest4.go +++ b/analyzer/testdata/src/filtertest/linetest4.go @@ -1,6 +1,6 @@ package filtertest func _() { - lineTest("", "line 4") // want `YES` + lineTest("", "line 4") // want `true` lineTest("", "line 4") } diff --git a/analyzer/testdata/src/filtertest/rules.go b/analyzer/testdata/src/filtertest/rules.go index c857a5f2..cabefad5 100644 --- a/analyzer/testdata/src/filtertest/rules.go +++ b/analyzer/testdata/src/filtertest/rules.go @@ -18,15 +18,15 @@ func testRules(m dsl.Matcher) { m.Match(`typeTest($x, "contains time.Time")`). Where(m["x"].Type.Underlying().Is(`struct{$*_; time.Time; $*_}`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "starts with time.Time")`). Where(m["x"].Type.Underlying().Is(`struct{time.Time; $*_}`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "non-underlying type test; T + T")`). Where(m["x"].Type.Is(`struct{$t; $t}`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x + $y)`). Where(m["x"].Type.Is(`string`) && m["y"].Type.Is("string")). @@ -63,11 +63,11 @@ func testRules(m dsl.Matcher) { Report(`$x !is(string) && !is(int)`) m.Match(`typeTest($x, "implements io.Reader")`). - Where(m["x"].Type.Implements(`io.Reader`)).Report(`YES`) + Where(m["x"].Type.Implements(`io.Reader`)).Report(`true`) m.Match(`typeTest($x, "implements foolib.Stringer")`). - Where(m["x"].Type.Implements(`foolib.Stringer`)).Report(`YES`) + Where(m["x"].Type.Implements(`foolib.Stringer`)).Report(`true`) m.Match(`typeTest($x, "implements error")`). - Where(m["x"].Type.Implements(`error`)).Report(`YES`) + Where(m["x"].Type.Implements(`error`)).Report(`true`) m.Match(`typeTest($*xs, "variadic implements error")`). Where(m["xs"].Type.Implements(`error`)).Report(`true`) @@ -77,27 +77,27 @@ func testRules(m dsl.Matcher) { m.Match(`typeTest($*xs, "variadic size==4")`).Where(m["xs"].Type.Size == 4).Report(`true`) m.Match(`typeTest($*xs, "variadic size==4")`).Where(!(m["xs"].Type.Size == 4)).Report(`false`) - m.Match(`typeTest($x, "size>=100")`).Where(m["x"].Type.Size >= 100).Report(`YES`) - m.Match(`typeTest($x, "size<=100")`).Where(m["x"].Type.Size <= 100).Report(`YES`) - m.Match(`typeTest($x, "size>100")`).Where(m["x"].Type.Size > 100).Report(`YES`) - m.Match(`typeTest($x, "size<100")`).Where(m["x"].Type.Size < 100).Report(`YES`) - m.Match(`typeTest($x, "size==100")`).Where(m["x"].Type.Size == 100).Report(`YES`) - m.Match(`typeTest($x, "size!=100")`).Where(m["x"].Type.Size != 100).Report(`YES`) + m.Match(`typeTest($x, "size>=100")`).Where(m["x"].Type.Size >= 100).Report(`true`) + m.Match(`typeTest($x, "size<=100")`).Where(m["x"].Type.Size <= 100).Report(`true`) + m.Match(`typeTest($x, "size>100")`).Where(m["x"].Type.Size > 100).Report(`true`) + m.Match(`typeTest($x, "size<100")`).Where(m["x"].Type.Size < 100).Report(`true`) + m.Match(`typeTest($x, "size==100")`).Where(m["x"].Type.Size == 100).Report(`true`) + m.Match(`typeTest($x, "size!=100")`).Where(m["x"].Type.Size != 100).Report(`true`) m.Match(`typeTest($x(), "func() int")`). Where(m["x"].Type.Is("func() int")). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x($*_), "func(int) int")`). Where(m["x"].Type.Is("func(int) int")). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x(), "func() string")`). Where(m["x"].Type.Is("func() string")). - Report(`YES`) + Report(`true`) - m.Match(`typeTest($t0 == $t1, "time==time")`).Where(m["t0"].Type.Is("time.Time")).Report(`YES`) - m.Match(`typeTest($t0 != $t1, "time!=time")`).Where(m["t1"].Type.Is("time.Time")).Report(`YES`) + m.Match(`typeTest($t0 == $t1, "time==time")`).Where(m["t0"].Type.Is("time.Time")).Report(`true`) + m.Match(`typeTest($t0 != $t1, "time!=time")`).Where(m["t1"].Type.Is("time.Time")).Report(`true`) m.Match(`pureTest($x)`). Where(m["x"].Pure). @@ -135,71 +135,71 @@ func testRules(m dsl.Matcher) { m.Match(`valueTest($*xs, "variadic value 5")`).Where(m["xs"].Value.Int() == 5).Report(`true`) m.Match(`valueTest($*xs, "variadic value 5")`).Where(!(m["xs"].Value.Int() == 5)).Report(`false`) - m.Match(`lineTest($x, "line 4")`).Where(m["x"].Line == 4).Report(`YES`) - m.Match(`lineTest($x, $y, "same line")`).Where(m["x"].Line == m["y"].Line).Report(`YES`) - m.Match(`lineTest($x, $y, "different line")`).Where(m["x"].Line != m["y"].Line).Report(`YES`) + m.Match(`lineTest($x, "line 4")`).Where(m["x"].Line == 4).Report(`true`) + m.Match(`lineTest($x, $y, "same line")`).Where(m["x"].Line == m["y"].Line).Report(`true`) + m.Match(`lineTest($x, $y, "different line")`).Where(m["x"].Line != m["y"].Line).Report(`true`) - m.Match(`textTest($x, "text=foo")`).Where(m["x"].Text == `foo`).Report(`YES`) - m.Match(`textTest($x, "text='foo'")`).Where(m["x"].Text == `"foo"`).Report(`YES`) - m.Match(`textTest($x, "text!='foo'")`).Where(m["x"].Text != `"foo"`).Report(`YES`) + m.Match(`textTest($x, "text=foo")`).Where(m["x"].Text == `foo`).Report(`true`) + m.Match(`textTest($x, "text='foo'")`).Where(m["x"].Text == `"foo"`).Report(`true`) + m.Match(`textTest($x, "text!='foo'")`).Where(m["x"].Text != `"foo"`).Report(`true`) - m.Match(`textTest($x, "matches d+")`).Where(m["x"].Text.Matches(`^\d+$`)).Report(`YES`) - m.Match(`textTest($x, "doesn't match [A-Z]")`).Where(!m["x"].Text.Matches(`[A-Z]`)).Report(`YES`) + m.Match(`textTest($x, "matches d+")`).Where(m["x"].Text.Matches(`^\d+$`)).Report(`true`) + m.Match(`textTest($x, "doesn't match [A-Z]")`).Where(!m["x"].Text.Matches(`[A-Z]`)).Report(`true`) - m.Match(`parensFilterTest($x, "type is error")`).Where((m["x"].Type.Is(`error`))).Report(`YES`) + m.Match(`parensFilterTest($x, "type is error")`).Where((m["x"].Type.Is(`error`))).Report(`true`) m.Match(`importsTest(os.PathSeparator, "path/filepath")`). Where(m.File().Imports("path/filepath")). - Report(`YES`) + Report(`true`) m.Match(`importsTest(os.PathListSeparator, "path/filepath")`). Where(m.File().Imports("path/filepath")). - Report(`YES`) + Report(`true`) m.Match(`fileTest("with foo prefix")`). Where(m.File().Name.Matches(`^foo_`)). - Report(`YES`) + Report(`true`) m.Match(`fileTest("f1.go")`). Where(m.File().Name.Matches(`^f1.go$`)). - Report(`YES`) + Report(`true`) m.Match(`(($x))`).Where(!m.File().PkgPath.Matches(`filtertest`)).Report(`suspicious double parens`) m.Match(`((($x)))`).Where(m.File().PkgPath.Matches(`filtertest`)).Report(`suspicious tripple parens`) m.Match(`nodeTest("3 identical expr statements in a row"); $x; $x; $x`).Where(m["x"].Node.Is(`ExprStmt`)).Report(`true`) - m.Match(`nodeTest($x, "Expr")`).Where(m["x"].Node.Is(`Expr`)).Report(`YES`) - m.Match(`nodeTest($x, "BasicLit")`).Where(m["x"].Node.Is(`BasicLit`)).Report(`YES`) - m.Match(`nodeTest($x, "Ident")`).Where(m["x"].Node.Is(`Ident`)).Report(`YES`) - m.Match(`nodeTest($x, "!Ident")`).Where(!m["x"].Node.Is(`Ident`)).Report(`YES`) - m.Match(`nodeTest($x, "IndexExpr")`).Where(m["x"].Node.Is(`IndexExpr`)).Report(`YES`) + m.Match(`nodeTest($x, "Expr")`).Where(m["x"].Node.Is(`Expr`)).Report(`true`) + m.Match(`nodeTest($x, "BasicLit")`).Where(m["x"].Node.Is(`BasicLit`)).Report(`true`) + m.Match(`nodeTest($x, "Ident")`).Where(m["x"].Node.Is(`Ident`)).Report(`true`) + m.Match(`nodeTest($x, "!Ident")`).Where(!m["x"].Node.Is(`Ident`)).Report(`true`) + m.Match(`nodeTest($x, "IndexExpr")`).Where(m["x"].Node.Is(`IndexExpr`)).Report(`true`) m.Match(`typeTest($x, "convertible to ([2]int)")`). Where(m["x"].Type.ConvertibleTo(`([2]int)`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "convertible to [][]int")`). Where(m["x"].Type.ConvertibleTo(`[][]int`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "assignable to map[*string]error")`). Where(m["x"].Type.AssignableTo(`map[*string]error`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "assignable to interface{}")`). Where(m["x"].Type.AssignableTo(`interface{}`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "is interface")`). Where(m["x"].Type.Is(`interface{ $*_ }`)). - Report(`YES`) + Report(`true`) m.Match(`typeTest($x, "underlying is interface")`). Where(m["x"].Type.Underlying().Is(`interface{ $*_ }`)). - Report(`YES`) + Report(`true`) m.Match(`textTest("", "root text test")`). Where(m["$$"].Text == `textTest("", "root text test")`). - Report(`YES`) + Report(`true`) } diff --git a/analyzer/testdata/src/gocritic/f1.go b/analyzer/testdata/src/gocritic/f1.go index f404cc73..e7ce0c92 100644 --- a/analyzer/testdata/src/gocritic/f1.go +++ b/analyzer/testdata/src/gocritic/f1.go @@ -12,12 +12,12 @@ import ( ) func selfAssign(x int, ys []string) { - x = x // want `suspicious self-assignment in x = x` + x = x // want `\Qsuspicious self-assignment in x = x` ys[0] = ys[0] // want `\Qsuspicious self-assignment in ys[0] = ys[0]` } func valSwap1(x, y int) (int, int) { - tmp := x // want `can use parallel assignment like x,y=y,x` + tmp := x // want `\Qcan use parallel assignment like x,y=y,x` x = y y = tmp return x, y @@ -61,7 +61,7 @@ func appendCombine2(xs []int, aa []int, bb []int) []int { func badCall(s string, xs []int) { _ = strings.Replace(s, "a", "b", 0) // want `\Qn=0 argument does nothing, maybe n=-1 is indended?` - _ = append(xs) // want `append called with 1 argument does nothing` + _ = append(xs) // want `\Qappend called with 1 argument does nothing` } func stringXbytes(s string, b []byte) { @@ -76,53 +76,53 @@ func assignOp(x, y int) { } func boolExprSimplify(a, b bool, i1, i2 int) { - _ = !!a // want `can simplify !!a to a` + _ = !!a // want `\Qcan simplify !!a to a` _ = !(i1 != i2) // want `\Qcan simplify !(i1!=i2) to i1==i2` _ = !(i1 == i2) // want `\Qcan simplify !(i1==i2) to i1!=i2` } func dupSubExprBad(i1, i2 int) { - _ = i1 != 0 && i1 != 1 && i1 != 0 // want `suspicious duplicated i1 != 0 in condition` - _ = i1 == 0 || i1 == 0 // want `suspicious identical LHS and RHS` - _ = i1 == i1 // want `suspicious identical LHS and RHS` - _ = i1 != i1 // want `suspicious identical LHS and RHS` - _ = i1 - i1 // want `suspicious identical LHS and RHS` + _ = i1 != 0 && i1 != 1 && i1 != 0 // want `\Qsuspicious duplicated i1 != 0 in condition` + _ = i1 == 0 || i1 == 0 // want `\Qsuspicious identical LHS and RHS` + _ = i1 == i1 // want `\Qsuspicious identical LHS and RHS` + _ = i1 != i1 // want `\Qsuspicious identical LHS and RHS` + _ = i1 - i1 // want `\Qsuspicious identical LHS and RHS` } func mapKey(x, y int) { _ = map[int]int{} _ = map[int]int{x + 1: 1, x + 2: 2} - _ = map[int]int{x: 1, x: 2} // want `suspicious duplicate key x` + _ = map[int]int{x: 1, x: 2} // want `\Qsuspicious duplicate key x` _ = map[int]int{ 10: 1, - x: 2, // want `suspicious duplicate key x` + x: 2, // want `\Qsuspicious duplicate key x` 30: 3, x: 4, 50: 5, } - _ = map[int]int{y: 1, x: 2, y: 3} // want `suspicious duplicate key y` + _ = map[int]int{y: 1, x: 2, y: 3} // want `\Qsuspicious duplicate key y` } func regexpMust(pat string) { regexp.Compile(pat) // OK: dynamic pattern - regexp.Compile("123") // want `can use MustCompile for const patterns` + regexp.Compile("123") // want `\Qcan use MustCompile for const patterns` const constPat = `hello` - regexp.CompilePOSIX(constPat) // want `can use MustCompile for const patterns` + regexp.CompilePOSIX(constPat) // want `\Qcan use MustCompile for const patterns` } func yodaStyleExpr(p *int) { - _ = nil != p // want `yoda-style expression` + _ = nil != p // want `\Qyoda-style expression` } func underef() { var k *[5]int - (*k)[2] = 3 // want `explicit array deref is redundant` + (*k)[2] = 3 // want `\Qexplicit array deref is redundant` var k2 **[2]int - _ = (**k2)[0] // want `explicit array deref is redundant` + _ = (**k2)[0] // want `\Qexplicit array deref is redundant` k2ptr := &k2 - _ = (***k2ptr)[1] // want `explicit array deref is redundant` + _ = (***k2ptr)[1] // want `\Qexplicit array deref is redundant` } func unslice() { @@ -177,21 +177,21 @@ func unslice() { } func switchWithOneCase1(x int) { - switch x { // want `should rewrite switch statement to if statement` + switch x { // want `\Qshould rewrite switch statement to if statement` case 1: println("ok") } } func switchWithOneCase2(x int) { - switch { // want `should rewrite switch statement to if statement` + switch { // want `\Qshould rewrite switch statement to if statement` case x == 1: println("ok") } } func typeSwitchOneCase1(x interface{}) int { - switch x := x.(type) { // want `should rewrite switch statement to if statement` + switch x := x.(type) { // want `\Qshould rewrite switch statement to if statement` case int: return x } @@ -199,7 +199,7 @@ func typeSwitchOneCase1(x interface{}) int { } func typeSwitchOneCase2(x interface{}) int { - switch x.(type) { // want `should rewrite switch statement to if statement` + switch x.(type) { // want `\Qshould rewrite switch statement to if statement` case int: return 1 } @@ -207,7 +207,7 @@ func typeSwitchOneCase2(x interface{}) int { } func switchTrue(b bool) { - switch true { // want `can omit true in switch` + switch true { // want `\Qcan omit true in switch` case b: return case !b: @@ -353,8 +353,8 @@ func offBy1(xs []int, ys []string) { } func wrapperFunc(s string) { - _ = strings.SplitN(s, ".", -1) // want `use Split` - _ = strings.Replace(s, "a", "b", -1) // want `use Replace` + _ = strings.SplitN(s, ".", -1) // want `\Quse Split` + _ = strings.Replace(s, "a", "b", -1) // want `\Quse Replace` _ = strings.Split(s, ".") _ = strings.ReplaceAll(s, "a", "b") @@ -377,21 +377,21 @@ type object struct { func suspiciousReturns() { _ = func(err error) error { - if err == nil { // want `returned expr is always nil; replace err with nil` + if err == nil { // want `\Qreturned expr is always nil; replace err with nil` return err } return nil } _ = func(o *object) *object { - if o == nil { // want `returned expr is always nil; replace o with nil` + if o == nil { // want `\Qreturned expr is always nil; replace o with nil` return o } return &object{} } _ = func(o *object) *byte { - if o.data == nil { // want `returned expr is always nil; replace o.data with nil` + if o.data == nil { // want `\Qreturned expr is always nil; replace o.data with nil` return o.data } return nil @@ -401,7 +401,7 @@ func suspiciousReturns() { if pointers[0][1][2]["ptr"] == nil { // want `\Qreturned expr is always nil; replace pointers[0][1][2]["ptr"] with nil` return pointers[0][1][2]["ptr"] } - if ptr := pointers[0][1][2]["ptr"]; ptr == nil { // want `returned expr is always nil; replace ptr with nil` + if ptr := pointers[0][1][2]["ptr"]; ptr == nil { // want `\Qreturned expr is always nil; replace ptr with nil` return ptr } return nil @@ -505,7 +505,7 @@ func rangeExprCopy() { { var xs [777]byte - for _, x := range xs { // want `xs copy can be avoided with &xs` + for _, x := range xs { // want `\Qxs copy can be avoided with &xs` _ = x } } diff --git a/analyzer/testdata/src/golint/file.go b/analyzer/testdata/src/golint/file.go index 0ae32e0f..aab8b8f2 100644 --- a/analyzer/testdata/src/golint/file.go +++ b/analyzer/testdata/src/golint/file.go @@ -59,7 +59,7 @@ func golintIfreturn() { _ = func() { if conds[0] { println("ok") - } else if conds[1] { // want `if block ends with a return statement, so drop this else and outdent its block` + } else if conds[1] { // want `\Qif block ends with a return statement, so drop this else and outdent its block` return } else { println("bad") @@ -67,7 +67,7 @@ func golintIfreturn() { } _ = func() { - if conds[0] { // want `if block ends with a return statement, so drop this else and outdent its block` + if conds[0] { // want `\Qif block ends with a return statement, so drop this else and outdent its block` return } else { println("bad") @@ -75,7 +75,7 @@ func golintIfreturn() { } _ = func(cond bool) int { - if cond { // want `if block ends with a return statement, so drop this else and outdent its block` + if cond { // want `\Qif block ends with a return statement, so drop this else and outdent its block` return 10 } else { return 20 diff --git a/analyzer/testdata/src/matching/file.go b/analyzer/testdata/src/matching/file.go index c1cfabaf..32e2d996 100644 --- a/analyzer/testdata/src/matching/file.go +++ b/analyzer/testdata/src/matching/file.go @@ -3,18 +3,18 @@ package golint func sink(args ...interface{}) {} func multiexpr() (int, int, int) { - sink(1, 1) // want `repeated expression in list` - _ = []int{0, 1, 1} // want `repeated expression in list` + sink(1, 1) // want `\Qrepeated expression in list` + _ = []int{0, 1, 1} // want `\Qrepeated expression in list` _ = []string{ "", - "x", // want `repeated expression in list` + "x", // want `\Qrepeated expression in list` "x", "", - "y", "y", // want `repeated expression in list` + "y", "y", // want `\Qrepeated expression in list` "", "z", } - return 1, 1, 0 // want `repeated expression in list` + return 1, 1, 0 // want `\Qrepeated expression in list` } diff --git a/analyzer/testdata/src/namedtype/nested/example.go b/analyzer/testdata/src/namedtype/nested/example.go index bb82374a..b6b98dc5 100644 --- a/analyzer/testdata/src/namedtype/nested/example.go +++ b/analyzer/testdata/src/namedtype/nested/example.go @@ -17,14 +17,14 @@ var sink interface{} type Element struct{} func example() { - sink = &list.Element{} // want `list Element` - sink = &listcont.Element{} // want `list Element` + sink = &list.Element{} // want `\Qlist Element` + sink = &listcont.Element{} // want `\Qlist Element` - sink = &htmltemplate.Template{} // want `html Template` - sink = &texttemplate.Template{} // want `text Template` + sink = &htmltemplate.Template{} // want `\Qhtml Template` + sink = &texttemplate.Template{} // want `\Qtext Template` - sink = &xnested.Element{} // want `x/nested Element` + sink = &xnested.Element{} // want `\Qx/nested Element` sink = &ynested.Element{} - sink = extra.NewValue() // want `extra Value` + sink = extra.NewValue() // want `\Qextra Value` } diff --git a/analyzer/testdata/src/namedtype/nested/example2.go b/analyzer/testdata/src/namedtype/nested/example2.go index 7d270e57..9f26f1da 100644 --- a/analyzer/testdata/src/namedtype/nested/example2.go +++ b/analyzer/testdata/src/namedtype/nested/example2.go @@ -9,5 +9,5 @@ func example2() { sink = &Element{} sink = &nested.Element{} - sink = extra.NewValue() // want `extra Value` + sink = extra.NewValue() // want `\Qextra Value` } diff --git a/analyzer/testdata/src/regression/issue68.go b/analyzer/testdata/src/regression/issue68.go index 8f72e3a8..c8743c4d 100644 --- a/analyzer/testdata/src/regression/issue68.go +++ b/analyzer/testdata/src/regression/issue68.go @@ -2,11 +2,11 @@ package regression import "testing" -func TestParallel(t *testing.T) { // want `Parallel test` +func TestParallel(t *testing.T) { // want `\QParallel test` t.Parallel() } -func TestNotParallel1(t *testing.T) { // want `Not a parallel test` +func TestNotParallel1(t *testing.T) { // want `\QNot a parallel test` t.Fatalf("This test should fail") } diff --git a/analyzer/testdata/src/revive/file.go b/analyzer/testdata/src/revive/file.go index 312b563a..03c654a0 100644 --- a/analyzer/testdata/src/revive/file.go +++ b/analyzer/testdata/src/revive/file.go @@ -6,25 +6,25 @@ import ( ) func callToGC() { - runtime.GC() // want `explicit call to GC` + runtime.GC() // want `\Qexplicit call to GC` } func atomicAssign() { var i64 int64 - i64 = atomic.AddInt64(&i64, 10) // want `direct assignment to atomic value` + i64 = atomic.AddInt64(&i64, 10) // want `\Qdirect assignment to atomic value` i64p := &i64 - *i64p = atomic.AddInt64(i64p, 10) // want `direct assignment to atomic value` + *i64p = atomic.AddInt64(i64p, 10) // want `\Qdirect assignment to atomic value` } func boolLiteralInExpr(a, b, c, d int) bool { var bar, yes bool - if bar == true { // want `omit bool literal in expression` + if bar == true { // want `\Qomit bool literal in expression` } - for getBool() || yes != false { // want `omit bool literal in expression` + for getBool() || yes != false { // want `\Qomit bool literal in expression` } - return b > c == false // want `omit bool literal in expression` + return b > c == false // want `\Qomit bool literal in expression` } diff --git a/analyzer/testdata/src/suggest/file.go b/analyzer/testdata/src/suggest/file.go index ea396037..e0bab36d 100644 --- a/analyzer/testdata/src/suggest/file.go +++ b/analyzer/testdata/src/suggest/file.go @@ -1,5 +1,5 @@ package suggest func example(x, y int) { - _ = (x == 1) || (y == 1) // want `suggestion: x == 1 || y == 1` + _ = (x == 1) || (y == 1) // want `\Qsuggestion: x == 1 || y == 1` } diff --git a/analyzer/testdata/src/testvendored/file.go b/analyzer/testdata/src/testvendored/file.go index 5a579c30..3c733320 100644 --- a/analyzer/testdata/src/testvendored/file.go +++ b/analyzer/testdata/src/testvendored/file.go @@ -9,13 +9,13 @@ import ( ) func example() { - err := fmt.Errorf("Failed to configure system. Error: %v", errors.New("test")) // want `nothing special, just testing the Errorf rule` + err := fmt.Errorf("Failed to configure system. Error: %v", errors.New("test")) // want `\Qnothing special, just testing the Errorf rule` logger := logging.GetLogger() - logger.Errorf("Failed to configure system. Error: %v", err) // want `Errors must be logged as a structured field` - logger.Errorf("Failed to configure system. Error: %v", err.Error()) // want `Errors must be logged as a structured field` + logger.Errorf("Failed to configure system. Error: %v", err) // want `\QErrors must be logged as a structured field` + logger.Errorf("Failed to configure system. Error: %v", err.Error()) // want `\QErrors must be logged as a structured field` name := "abc" logger.Errorf("Configure system %s", name) - logger.Errorf("Failed to configure system %s. Error: %v", strings.ToLower(name), err.Error()) // want `Errors must be logged as a structured field` + logger.Errorf("Failed to configure system %s. Error: %v", strings.ToLower(name), err.Error()) // want `\QErrors must be logged as a structured field` }