mirror of
https://github.com/mgechev/revive.git
synced 2025-02-09 13:37:14 +02:00
empty-block: Fix false positive on select {} (#805)
This fixes a false positive reported by revive on the following: select {} This is a way to block the program indefinitely. It is used in cases like: - Running a long-running server in a background thread and blocking `main` from exiting until the application dies. This is something you might do if your process has multiple servers/listeners in the same process. ```go go grpcListenAndServe() go httpListenAndServe() go logFlusher() select {} ``` - In programs compiled to WASM to prevent the application from exiting, so that the Javascript components may interact with it. ```go func main() { js.Global().Set("foo", foo) select {} } ``` Without this, one may see an error like, "Error: Go program has already exited" As a workaround, these programs can block forever by receiving from a throwaway channel (`<-make(chan struct{})`), but `select {}` is still a completely valid way of doing this, so supporting it makes sense. The issue was previously reported in #698 but was closed because the author was satisfied with a `//nolint` comment. Now that this rule is part of the default rule set (#799) the case for addressing the false positive is stronger. Resolves #804
This commit is contained in:
parent
5db07b5c97
commit
b03e54f617
@ -40,6 +40,9 @@ func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
|
|||||||
case *ast.FuncLit:
|
case *ast.FuncLit:
|
||||||
w.ignore[n.Body] = true
|
w.ignore[n.Body] = true
|
||||||
return w
|
return w
|
||||||
|
case *ast.SelectStmt:
|
||||||
|
w.ignore[n.Body] = true
|
||||||
|
return w
|
||||||
case *ast.RangeStmt:
|
case *ast.RangeStmt:
|
||||||
if len(n.Body.List) == 0 {
|
if len(n.Body.List) == 0 {
|
||||||
w.onFailure(lint.Failure{
|
w.onFailure(lint.Failure{
|
||||||
|
13
testdata/empty-block.go
vendored
13
testdata/empty-block.go
vendored
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
package fixtures
|
package fixtures
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
func f(x int) {} // Must not match
|
func f(x int) {} // Must not match
|
||||||
|
|
||||||
type foo struct{}
|
type foo struct{}
|
||||||
@ -9,6 +11,12 @@ type foo struct{}
|
|||||||
func (f foo) f(x *int) {} // Must not match
|
func (f foo) f(x *int) {} // Must not match
|
||||||
func (f *foo) g(y *int) {} // Must not match
|
func (f *foo) g(y *int) {} // Must not match
|
||||||
|
|
||||||
|
|
||||||
|
func h() {
|
||||||
|
go http.ListenAndServe()
|
||||||
|
select {} // Must not match
|
||||||
|
}
|
||||||
|
|
||||||
func g(f func() bool) {
|
func g(f func() bool) {
|
||||||
{ // MATCH /this block is empty, you can remove it/
|
{ // MATCH /this block is empty, you can remove it/
|
||||||
}
|
}
|
||||||
@ -44,4 +52,9 @@ func g(f func() bool) {
|
|||||||
for range s { // MATCH /this block is empty, you can remove it/
|
for range s { // MATCH /this block is empty, you can remove it/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-c:
|
||||||
|
if ok { // MATCH /this block is empty, you can remove it/
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user