mirror of https://github.com/golang/go.git
gopls/internal/lsp/source: avoid panic(nil)
The previous code used panic(nil) as a longjump. However, if a library function such as Node.Pos() were to panic(nil), we would catch it spuriously instead of reporting the panic by crashing the program. This change uses a new type, found, as a sentinal for the non-local jump. Updates golang/go#25448 Change-Id: I2439432a7ca477d0c25c9c848a98308a378b089b Reviewed-on: https://go-review.googlesource.com/c/tools/+/452515 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Alan Donovan <adonovan@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
41c70c91bc
commit
57f56abcb0
|
|
@ -895,10 +895,14 @@ func anyNonEmpty(x []string) bool {
|
|||
//
|
||||
// It returns (nil, nil) if no Field or Decl is found at pos.
|
||||
func FindDeclAndField(files []*ast.File, pos token.Pos) (decl ast.Decl, field *ast.Field) {
|
||||
// panic(nil) breaks off the traversal and
|
||||
// panic(found{}) breaks off the traversal and
|
||||
// causes the function to return normally.
|
||||
type found struct{}
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
switch x := recover().(type) {
|
||||
case nil:
|
||||
case found:
|
||||
default:
|
||||
panic(x)
|
||||
}
|
||||
}()
|
||||
|
|
@ -930,7 +934,7 @@ func FindDeclAndField(files []*ast.File, pos token.Pos) (decl ast.Decl, field *a
|
|||
break
|
||||
}
|
||||
}
|
||||
panic(nil) // found
|
||||
panic(found{})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -953,7 +957,7 @@ func FindDeclAndField(files []*ast.File, pos token.Pos) (decl ast.Decl, field *a
|
|||
case *ast.FuncDecl:
|
||||
if n.Name.Pos() == pos {
|
||||
decl = n
|
||||
panic(nil) // found
|
||||
panic(found{})
|
||||
}
|
||||
|
||||
case *ast.GenDecl:
|
||||
|
|
@ -962,13 +966,13 @@ func FindDeclAndField(files []*ast.File, pos token.Pos) (decl ast.Decl, field *a
|
|||
case *ast.TypeSpec:
|
||||
if spec.Name.Pos() == pos {
|
||||
decl = n
|
||||
panic(nil) // found
|
||||
panic(found{})
|
||||
}
|
||||
case *ast.ValueSpec:
|
||||
for _, id := range spec.Names {
|
||||
if id.Pos() == pos {
|
||||
decl = n
|
||||
panic(nil) // found
|
||||
panic(found{})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue