mirror of https://github.com/golang/go.git
gopls/internal/regtest: add a test for using staticcheck with generics
For golang/go#52159 Change-Id: I08120331b7f5c9eb06feac0d0eeb76a9a7b629df Reviewed-on: https://go-review.googlesource.com/c/tools/+/399914 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Dylan Le <dungtuanle@google.com>
This commit is contained in:
parent
1a5eed31fb
commit
728485ffcb
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2022 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 misc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
|
||||
. "golang.org/x/tools/internal/lsp/regtest"
|
||||
)
|
||||
|
||||
func TestStaticcheckGenerics(t *testing.T) {
|
||||
testenv.NeedsGo1Point(t, 18) // generics were introduced in Go 1.18
|
||||
|
||||
const files = `
|
||||
-- go.mod --
|
||||
module mod.com
|
||||
|
||||
go 1.18
|
||||
-- a/a.go --
|
||||
package a
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Zero[P any]() P {
|
||||
var p P
|
||||
return p
|
||||
}
|
||||
|
||||
type Inst[P any] struct {
|
||||
Field P
|
||||
}
|
||||
|
||||
func testGenerics[P *T, T any](p P) {
|
||||
// Calls to instantiated functions should not break checks.
|
||||
slice := Zero[string]()
|
||||
sort.Slice(slice, func(i, j int) bool {
|
||||
return slice[i] < slice[j]
|
||||
})
|
||||
|
||||
// Usage of instantiated fields should not break checks.
|
||||
g := Inst[string]{"hello"}
|
||||
g.Field = strings.TrimLeft(g.Field, "12234")
|
||||
|
||||
// Use of type parameters should not break checks.
|
||||
var q P
|
||||
p = q // SA4009: p is overwritten before its first use
|
||||
q = &*p // SA4001: &* will be simplified
|
||||
}
|
||||
|
||||
|
||||
// FooErr should be called ErrFoo (ST1012)
|
||||
var FooErr error = errors.New("foo")
|
||||
`
|
||||
|
||||
WithOptions(EditorConfig{
|
||||
Settings: map[string]interface{}{
|
||||
"staticcheck": true,
|
||||
},
|
||||
}).Run(t, files, func(t *testing.T, env *Env) {
|
||||
env.OpenFile("a/a.go")
|
||||
env.Await(
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", "sort.Slice", "sortslice"),
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", "sort.Slice.(slice)", "SA1028"),
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", "var (FooErr)", "ST1012"),
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", `"12234"`, "SA1024"),
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", "testGenerics.*(p P)", "SA4009"),
|
||||
env.DiagnosticAtRegexpFromSource("a/a.go", "q = (&\\*p)", "SA4001"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
@ -465,6 +465,9 @@ type DiagnosticExpectation struct {
|
|||
|
||||
// path is the scratch workdir-relative path to the file being asserted on.
|
||||
path string
|
||||
|
||||
// optionally, the diagnostic source
|
||||
source string
|
||||
}
|
||||
|
||||
// Check implements the Expectation interface.
|
||||
|
|
@ -489,6 +492,9 @@ func (e DiagnosticExpectation) Check(s State) Verdict {
|
|||
continue
|
||||
}
|
||||
}
|
||||
if e.source != "" && e.source != d.Source {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
|
@ -515,6 +521,9 @@ func (e DiagnosticExpectation) Description() string {
|
|||
if e.message != "" {
|
||||
desc += fmt.Sprintf(" with message %q", e.message)
|
||||
}
|
||||
if e.source != "" {
|
||||
desc += fmt.Sprintf(" from source %q", e.source)
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
|
|
@ -619,6 +628,14 @@ func (e *Env) DiagnosticAtRegexpWithMessage(name, re, msg string) DiagnosticExpe
|
|||
return DiagnosticExpectation{path: name, pos: &pos, re: re, present: true, message: msg}
|
||||
}
|
||||
|
||||
// DiagnosticAtRegexpFromSource expects a diagnostic at the first position
|
||||
// matching re, from the given source.
|
||||
func (e *Env) DiagnosticAtRegexpFromSource(name, re, source string) DiagnosticExpectation {
|
||||
e.T.Helper()
|
||||
pos := e.RegexpSearch(name, re)
|
||||
return DiagnosticExpectation{path: name, pos: &pos, re: re, present: true, source: source}
|
||||
}
|
||||
|
||||
// DiagnosticAt asserts that there is a diagnostic entry at the position
|
||||
// specified by line and col, for the workdir-relative path name.
|
||||
func DiagnosticAt(name string, line, col int) DiagnosticExpectation {
|
||||
|
|
|
|||
Loading…
Reference in New Issue