golang.org/x/tools/gopls@v0.15.3/internal/test/integration/misc/staticcheck_test.go (about) 1 // Copyright 2022 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 misc 6 7 import ( 8 "testing" 9 10 "golang.org/x/tools/internal/testenv" 11 12 . "golang.org/x/tools/gopls/internal/test/integration" 13 ) 14 15 func TestStaticcheckGenerics(t *testing.T) { 16 testenv.NeedsGo1Point(t, 20) // staticcheck requires go1.20+ 17 18 const files = ` 19 -- go.mod -- 20 module mod.com 21 22 go 1.18 23 -- a/a.go -- 24 package a 25 26 import ( 27 "errors" 28 "sort" 29 "strings" 30 ) 31 32 func Zero[P any]() P { 33 var p P 34 return p 35 } 36 37 type Inst[P any] struct { 38 Field P 39 } 40 41 func testGenerics[P *T, T any](p P) { 42 // Calls to instantiated functions should not break checks. 43 slice := Zero[string]() 44 sort.Slice(slice, func(i, j int) bool { 45 return slice[i] < slice[j] 46 }) 47 48 // Usage of instantiated fields should not break checks. 49 g := Inst[string]{"hello"} 50 g.Field = strings.TrimLeft(g.Field, "12234") 51 52 // Use of type parameters should not break checks. 53 var q P 54 p = q // SA4009: p is overwritten before its first use 55 q = &*p // SA4001: &* will be simplified 56 } 57 58 59 // FooErr should be called ErrFoo (ST1012) 60 var FooErr error = errors.New("foo") 61 ` 62 63 WithOptions( 64 Settings{"staticcheck": true}, 65 ).Run(t, files, func(t *testing.T, env *Env) { 66 env.OpenFile("a/a.go") 67 env.AfterChange( 68 Diagnostics(env.AtRegexp("a/a.go", "sort.Slice"), FromSource("sortslice")), 69 Diagnostics(env.AtRegexp("a/a.go", "sort.Slice.(slice)"), FromSource("SA1028")), 70 Diagnostics(env.AtRegexp("a/a.go", "var (FooErr)"), FromSource("ST1012")), 71 Diagnostics(env.AtRegexp("a/a.go", `"12234"`), FromSource("SA1024")), 72 Diagnostics(env.AtRegexp("a/a.go", "testGenerics.*(p P)"), FromSource("SA4009")), 73 Diagnostics(env.AtRegexp("a/a.go", "q = (&\\*p)"), FromSource("SA4001")), 74 ) 75 }) 76 } 77 78 // Test for golang/go#56270: an analysis with related info should not panic if 79 // analysis.RelatedInformation.End is not set. 80 func TestStaticcheckRelatedInfo(t *testing.T) { 81 testenv.NeedsGo1Point(t, 20) // staticcheck is only supported at Go 1.20+ 82 const files = ` 83 -- go.mod -- 84 module mod.test 85 86 go 1.18 87 -- p.go -- 88 package p 89 90 import ( 91 "fmt" 92 ) 93 94 func Foo(enabled interface{}) { 95 if enabled, ok := enabled.(bool); ok { 96 } else { 97 _ = fmt.Sprintf("invalid type %T", enabled) // enabled is always bool here 98 } 99 } 100 ` 101 102 WithOptions( 103 Settings{"staticcheck": true}, 104 ).Run(t, files, func(t *testing.T, env *Env) { 105 env.OpenFile("p.go") 106 env.AfterChange( 107 Diagnostics(env.AtRegexp("p.go", ", (enabled)"), FromSource("SA9008")), 108 ) 109 }) 110 }