mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
go/analysis: rename reportNodef to ReportRangef
This adds (or makes exported) a convenience function for reporting diagnostics with a node directly (which is what folks usually want). Change-Id: Ieb7ef2703f99d3a24ba7e48a779be62a7761cd0c Reviewed-on: https://go-review.googlesource.com/c/tools/+/180237 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
parent
b394bd8bba
commit
e3efbe408c
@ -163,13 +163,19 @@ func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) {
|
||||
pass.Report(Diagnostic{Pos: pos, Message: msg})
|
||||
}
|
||||
|
||||
// reportNodef is a helper function that reports a Diagnostic using the
|
||||
// range denoted by the AST node.
|
||||
//
|
||||
// WARNING: This is an experimental API and may change in the future.
|
||||
func (pass *Pass) reportNodef(node ast.Node, format string, args ...interface{}) {
|
||||
// The Range interface provides a range. It's equivalent to and satisfied by
|
||||
// ast.Node.
|
||||
type Range interface {
|
||||
Pos() token.Pos // position of first character belonging to the node
|
||||
End() token.Pos // position of first character immediately after the node
|
||||
}
|
||||
|
||||
// ReportRangef is a helper function that reports a Diagnostic using the
|
||||
// range provided. ast.Node values can be passed in as the range because
|
||||
// they satisfy the Range interface.
|
||||
func (pass *Pass) ReportRangef(rng Range, format string, args ...interface{}) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
pass.Report(Diagnostic{Pos: node.Pos(), End: node.End(), Message: msg})
|
||||
pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg})
|
||||
}
|
||||
|
||||
func (pass *Pass) String() string {
|
||||
|
@ -91,6 +91,6 @@ func checkAtomicAddAssignment(pass *analysis.Pass, left ast.Expr, call *ast.Call
|
||||
}
|
||||
|
||||
if broken {
|
||||
pass.Reportf(left.Pos(), "direct assignment to atomic value")
|
||||
pass.ReportRangef(left, "direct assignment to atomic value")
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ func check64BitAlignment(pass *analysis.Pass, funcName string, arg ast.Expr) {
|
||||
return // 64-bit aligned
|
||||
}
|
||||
|
||||
pass.Reportf(arg.Pos(), "address of non 64-bit aligned field .%s passed to atomic.%s", tvar.Name(), funcName)
|
||||
pass.ReportRangef(arg, "address of non 64-bit aligned field .%s passed to atomic.%s", tvar.Name(), funcName)
|
||||
}
|
||||
|
||||
// imports reports whether pkg has path among its direct imports.
|
||||
|
@ -100,7 +100,7 @@ func (op boolOp) checkRedundant(pass *analysis.Pass, exprs []ast.Expr) {
|
||||
for _, e := range exprs {
|
||||
efmt := analysisutil.Format(pass.Fset, e)
|
||||
if seen[efmt] {
|
||||
pass.Reportf(e.Pos(), "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt)
|
||||
pass.ReportRangef(e, "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt)
|
||||
} else {
|
||||
seen[efmt] = true
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (op boolOp) checkSuspect(pass *analysis.Pass, exprs []ast.Expr) {
|
||||
if prev, found := seen[xfmt]; found {
|
||||
// checkRedundant handles the case in which efmt == prev.
|
||||
if efmt != prev {
|
||||
pass.Reportf(e.Pos(), "suspect %s: %s %s %s", op.name, efmt, op.tok, prev)
|
||||
pass.ReportRangef(e, "suspect %s: %s %s %s", op.name, efmt, op.tok, prev)
|
||||
}
|
||||
} else {
|
||||
seen[xfmt] = efmt
|
||||
|
@ -97,7 +97,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
return
|
||||
}
|
||||
|
||||
pass.Reportf(cl.Pos(), "%s composite literal uses unkeyed fields", typeName)
|
||||
pass.ReportRangef(cl, "%s composite literal uses unkeyed fields", typeName)
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
func checkCopyLocksAssign(pass *analysis.Pass, as *ast.AssignStmt) {
|
||||
for i, x := range as.Rhs {
|
||||
if path := lockPathRhs(pass, x); path != nil {
|
||||
pass.Reportf(x.Pos(), "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path)
|
||||
pass.ReportRangef(x, "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,7 @@ func checkCopyLocksGenDecl(pass *analysis.Pass, gd *ast.GenDecl) {
|
||||
valueSpec := spec.(*ast.ValueSpec)
|
||||
for i, x := range valueSpec.Values {
|
||||
if path := lockPathRhs(pass, x); path != nil {
|
||||
pass.Reportf(x.Pos(), "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path)
|
||||
pass.ReportRangef(x, "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) {
|
||||
x = node.Value
|
||||
}
|
||||
if path := lockPathRhs(pass, x); path != nil {
|
||||
pass.Reportf(x.Pos(), "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path)
|
||||
pass.ReportRangef(x, "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,7 +111,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) {
|
||||
func checkCopyLocksReturnStmt(pass *analysis.Pass, rs *ast.ReturnStmt) {
|
||||
for _, x := range rs.Results {
|
||||
if path := lockPathRhs(pass, x); path != nil {
|
||||
pass.Reportf(x.Pos(), "return copies lock value: %v", path)
|
||||
pass.ReportRangef(x, "return copies lock value: %v", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,7 @@ func checkCopyLocksCallExpr(pass *analysis.Pass, ce *ast.CallExpr) {
|
||||
}
|
||||
for _, x := range ce.Args {
|
||||
if path := lockPathRhs(pass, x); path != nil {
|
||||
pass.Reportf(x.Pos(), "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path)
|
||||
pass.ReportRangef(x, "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,7 +146,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t
|
||||
if recv != nil && len(recv.List) > 0 {
|
||||
expr := recv.List[0].Type
|
||||
if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil {
|
||||
pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path)
|
||||
pass.ReportRangef(expr, "%s passes lock by value: %v", name, path)
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t
|
||||
for _, field := range typ.Params.List {
|
||||
expr := field.Type
|
||||
if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil {
|
||||
pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path)
|
||||
pass.ReportRangef(expr, "%s passes lock by value: %v", name, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
return
|
||||
}
|
||||
if fn.FullName() == "reflect.DeepEqual" && hasError(pass, call.Args[0]) && hasError(pass, call.Args[1]) {
|
||||
pass.Reportf(call.Pos(), "avoid using reflect.DeepEqual with errors")
|
||||
pass.ReportRangef(call, "avoid using reflect.DeepEqual with errors")
|
||||
}
|
||||
})
|
||||
return nil, nil
|
||||
|
@ -51,7 +51,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
return // not enough arguments, e.g. called with return values of another function
|
||||
}
|
||||
if fn.FullName() == "errors.As" && !pointerToInterfaceOrError(pass, call.Args[1]) {
|
||||
pass.Reportf(call.Pos(), "second argument to errors.As must be a pointer to an interface or a type implementing error")
|
||||
pass.ReportRangef(call, "second argument to errors.As must be a pointer to an interface or a type implementing error")
|
||||
}
|
||||
})
|
||||
return nil, nil
|
||||
|
@ -85,7 +85,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
}
|
||||
|
||||
if resp.Obj == root.Obj {
|
||||
pass.Reportf(root.Pos(), "using %s before checking for errors", resp.Name)
|
||||
pass.ReportRangef(root, "using %s before checking for errors", resp.Name)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
@ -119,7 +119,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
}
|
||||
for _, v := range vars {
|
||||
if v.Obj == id.Obj {
|
||||
pass.Reportf(id.Pos(), "loop variable %s captured by func literal",
|
||||
pass.ReportRangef(id, "loop variable %s captured by func literal",
|
||||
id.Name)
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func runFunc(pass *analysis.Pass, node ast.Node) {
|
||||
}
|
||||
if id != nil {
|
||||
if id.Name == "_" {
|
||||
pass.Reportf(id.Pos(),
|
||||
pass.ReportRangef(id,
|
||||
"the cancel function returned by context.%s should be called, not discarded, to avoid a context leak",
|
||||
n.(*ast.SelectorExpr).Sel.Name)
|
||||
} else if v, ok := pass.TypesInfo.Uses[id].(*types.Var); ok {
|
||||
@ -174,8 +174,8 @@ func runFunc(pass *analysis.Pass, node ast.Node) {
|
||||
for v, stmt := range cancelvars {
|
||||
if ret := lostCancelPath(pass, g, v, stmt, sig); ret != nil {
|
||||
lineno := pass.Fset.Position(stmt.Pos()).Line
|
||||
pass.Reportf(stmt.Pos(), "the %s function is not used on all paths (possible context leak)", v.Name())
|
||||
pass.Reportf(ret.Pos(), "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno)
|
||||
pass.ReportRangef(stmt, "the %s function is not used on all paths (possible context leak)", v.Name())
|
||||
pass.ReportRangef(ret, "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
return
|
||||
}
|
||||
|
||||
pass.Reportf(e.Pos(), "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ)
|
||||
pass.ReportRangef(e, "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ)
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
eq := strings.IndexByte(pair, '=')
|
||||
result[pair[:eq]] = pair[1+eq:]
|
||||
}
|
||||
pass.Reportf(spec.Pos(), "%s", strings.Join(fact, " "))
|
||||
pass.ReportRangef(spec, "%s", strings.Join(fact, " "))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, k
|
||||
if kind == KindPrint {
|
||||
desc = "print"
|
||||
}
|
||||
pass.Reportf(call.Pos(), "missing ... in args forwarded to %s-like function", desc)
|
||||
pass.ReportRangef(call, "missing ... in args forwarded to %s-like function", desc)
|
||||
return
|
||||
}
|
||||
fn := w.obj
|
||||
@ -617,7 +617,7 @@ func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, fn *types.F
|
||||
if maxArgNum != len(call.Args) {
|
||||
expect := maxArgNum - firstArg
|
||||
numArgs := len(call.Args) - firstArg
|
||||
pass.Reportf(call.Pos(), "%s call needs %v but has %v", fn.Name(), count(expect, "arg"), count(numArgs, "arg"))
|
||||
pass.ReportRangef(call, "%s call needs %v but has %v", fn.Name(), count(expect, "arg"), count(numArgs, "arg"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -658,13 +658,13 @@ func (s *formatState) parseIndex() bool {
|
||||
ok = false
|
||||
s.nbytes = strings.Index(s.format, "]")
|
||||
if s.nbytes < 0 {
|
||||
s.pass.Reportf(s.call.Pos(), "%s format %s is missing closing ]", s.name, s.format)
|
||||
s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format)
|
||||
return false
|
||||
}
|
||||
}
|
||||
arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
|
||||
if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) {
|
||||
s.pass.Reportf(s.call.Pos(), "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes])
|
||||
s.pass.ReportRangef(s.call, "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes])
|
||||
return false
|
||||
}
|
||||
s.nbytes++ // skip ']'
|
||||
@ -741,7 +741,7 @@ func parsePrintfVerb(pass *analysis.Pass, call *ast.CallExpr, name, format strin
|
||||
return nil
|
||||
}
|
||||
if state.nbytes == len(state.format) {
|
||||
pass.Reportf(call.Pos(), "%s format %s is missing verb at end of string", name, state.format)
|
||||
pass.ReportRangef(call.Fun, "%s format %s is missing verb at end of string", name, state.format)
|
||||
return nil
|
||||
}
|
||||
verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:])
|
||||
@ -837,7 +837,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
|
||||
if !formatter {
|
||||
if !found {
|
||||
pass.Reportf(call.Pos(), "%s format %s has unknown verb %c", state.name, state.format, state.verb)
|
||||
pass.ReportRangef(call, "%s format %s has unknown verb %c", state.name, state.format, state.verb)
|
||||
return false
|
||||
}
|
||||
for _, flag := range state.flags {
|
||||
@ -847,7 +847,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
continue
|
||||
}
|
||||
if !strings.ContainsRune(v.flags, rune(flag)) {
|
||||
pass.Reportf(call.Pos(), "%s format %s has unrecognized flag %c", state.name, state.format, flag)
|
||||
pass.ReportRangef(call, "%s format %s has unrecognized flag %c", state.name, state.format, flag)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -866,7 +866,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
}
|
||||
arg := call.Args[argNum]
|
||||
if !matchArgType(pass, argInt, nil, arg) {
|
||||
pass.Reportf(call.Pos(), "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
pass.ReportRangef(call, "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -880,7 +880,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
}
|
||||
arg := call.Args[argNum]
|
||||
if isFunctionValue(pass, arg) && state.verb != 'p' && state.verb != 'T' {
|
||||
pass.Reportf(call.Pos(), "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
return false
|
||||
}
|
||||
if !matchArgType(pass, v.typ, nil, arg) {
|
||||
@ -888,11 +888,11 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o
|
||||
if typ := pass.TypesInfo.Types[arg].Type; typ != nil {
|
||||
typeString = typ.String()
|
||||
}
|
||||
pass.Reportf(call.Pos(), "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString)
|
||||
pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString)
|
||||
return false
|
||||
}
|
||||
if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) && recursiveStringer(pass, arg) {
|
||||
pass.Reportf(call.Pos(), "%s format %s with arg %s causes recursive String method call", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
pass.ReportRangef(call, "%s format %s with arg %s causes recursive String method call", state.name, state.format, analysisutil.Format(pass.Fset, arg))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -978,7 +978,7 @@ func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, formatArg int, sta
|
||||
// There are bad indexes in the format or there are fewer arguments than the format needs.
|
||||
// This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
|
||||
arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed.
|
||||
pass.Reportf(call.Pos(), "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg"))
|
||||
pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg"))
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1029,7 +1029,7 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
|
||||
if sel, ok := call.Args[0].(*ast.SelectorExpr); ok {
|
||||
if x, ok := sel.X.(*ast.Ident); ok {
|
||||
if x.Name == "os" && strings.HasPrefix(sel.Sel.Name, "Std") {
|
||||
pass.Reportf(call.Pos(), "%s does not take io.Writer but has first arg %s", fn.Name(), analysisutil.Format(pass.Fset, call.Args[0]))
|
||||
pass.ReportRangef(call, "%s does not take io.Writer but has first arg %s", fn.Name(), analysisutil.Format(pass.Fset, call.Args[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1043,7 +1043,7 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
|
||||
if strings.Contains(s, "%") {
|
||||
m := printFormatRE.FindStringSubmatch(s)
|
||||
if m != nil {
|
||||
pass.Reportf(call.Pos(), "%s call has possible formatting directive %s", fn.Name(), m[0])
|
||||
pass.ReportRangef(call, "%s call has possible formatting directive %s", fn.Name(), m[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1053,16 +1053,16 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
|
||||
if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
|
||||
str, _ := strconv.Unquote(lit.Value)
|
||||
if strings.HasSuffix(str, "\n") {
|
||||
pass.Reportf(call.Pos(), "%s arg list ends with redundant newline", fn.Name())
|
||||
pass.ReportRangef(call, "%s arg list ends with redundant newline", fn.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, arg := range args {
|
||||
if isFunctionValue(pass, arg) {
|
||||
pass.Reportf(call.Pos(), "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg))
|
||||
pass.ReportRangef(call, "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg))
|
||||
}
|
||||
if recursiveStringer(pass, arg) {
|
||||
pass.Reportf(call.Pos(), "%s arg %s causes recursive call to String method", fn.Name(), analysisutil.Format(pass.Fset, arg))
|
||||
pass.ReportRangef(call, "%s arg %s causes recursive call to String method", fn.Name(), analysisutil.Format(pass.Fset, arg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ func checkShadowAssignment(pass *analysis.Pass, spans map[types.Object]span, a *
|
||||
for _, expr := range a.Lhs {
|
||||
ident, ok := expr.(*ast.Ident)
|
||||
if !ok {
|
||||
pass.Reportf(expr.Pos(), "invalid AST: short variable declaration of non-identifier")
|
||||
pass.ReportRangef(expr, "invalid AST: short variable declaration of non-identifier")
|
||||
return
|
||||
}
|
||||
checkShadowing(pass, spans, ident)
|
||||
@ -182,7 +182,7 @@ func idiomaticShortRedecl(pass *analysis.Pass, a *ast.AssignStmt) bool {
|
||||
for i, expr := range a.Lhs {
|
||||
lhs, ok := expr.(*ast.Ident)
|
||||
if !ok {
|
||||
pass.Reportf(expr.Pos(), "invalid AST: short variable declaration of non-identifier")
|
||||
pass.ReportRangef(expr, "invalid AST: short variable declaration of non-identifier")
|
||||
return true // Don't do any more processing.
|
||||
}
|
||||
switch rhs := a.Rhs[i].(type) {
|
||||
@ -230,7 +230,7 @@ func checkShadowDecl(pass *analysis.Pass, spans map[types.Object]span, d *ast.Ge
|
||||
for _, spec := range d.Specs {
|
||||
valueSpec, ok := spec.(*ast.ValueSpec)
|
||||
if !ok {
|
||||
pass.Reportf(spec.Pos(), "invalid AST: var GenDecl not ValueSpec")
|
||||
pass.ReportRangef(spec, "invalid AST: var GenDecl not ValueSpec")
|
||||
return
|
||||
}
|
||||
// Don't complain about deliberate redeclarations of the form
|
||||
@ -274,7 +274,7 @@ func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast
|
||||
// the shadowing identifier.
|
||||
span, ok := spans[shadowed]
|
||||
if !ok {
|
||||
pass.Reportf(ident.Pos(), "internal error: no range for %q", ident.Name)
|
||||
pass.ReportRangef(ident, "internal error: no range for %q", ident.Name)
|
||||
return
|
||||
}
|
||||
if !span.contains(ident.Pos()) {
|
||||
@ -284,6 +284,6 @@ func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast
|
||||
// Don't complain if the types differ: that implies the programmer really wants two different things.
|
||||
if types.Identical(obj.Type(), shadowed.Type()) {
|
||||
line := pass.Fset.Position(shadowed.Pos()).Line
|
||||
pass.Reportf(ident.Pos(), "declaration of %q shadows declaration at line %d", obj.Name(), line)
|
||||
pass.ReportRangef(ident, "declaration of %q shadows declaration at line %d", obj.Name(), line)
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,6 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
|
||||
size := 8 * pass.TypesSizes.Sizeof(t)
|
||||
if amt >= size {
|
||||
ident := analysisutil.Format(pass.Fset, x)
|
||||
pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt)
|
||||
pass.ReportRangef(node, "%s (%d bits) too small for shift of %d", ident, size, amt)
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) {
|
||||
actual = strings.TrimPrefix(actual, "func")
|
||||
actual = id.Name + actual
|
||||
|
||||
pass.Reportf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
|
||||
pass.ReportRangef(id, "method %s should have signature %s", actual, expectFmt)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ func (d *deadState) findDead(stmt ast.Stmt) {
|
||||
case *ast.EmptyStmt:
|
||||
// do not warn about unreachable empty statements
|
||||
default:
|
||||
d.pass.Reportf(stmt.Pos(), "unreachable code")
|
||||
d.pass.ReportRangef(stmt, "unreachable code")
|
||||
d.reachable = true // silence error about next statement
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
|
||||
if hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) &&
|
||||
hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) &&
|
||||
!isSafeUintptr(pass.TypesInfo, x.Args[0]) {
|
||||
pass.Reportf(x.Pos(), "possible misuse of unsafe.Pointer")
|
||||
pass.ReportRangef(x, "possible misuse of unsafe.Pointer")
|
||||
}
|
||||
})
|
||||
return nil, nil
|
||||
|
2
internal/lsp/testdata/analyzer/bad_test.go
vendored
2
internal/lsp/testdata/analyzer/bad_test.go
vendored
@ -10,7 +10,7 @@ func Testbad(t *testing.T) { //@diag("", "tests", "Testbad has malformed name: f
|
||||
var x sync.Mutex
|
||||
_ = x //@diag("x", "copylocks", "assignment copies lock value to _: sync.Mutex")
|
||||
|
||||
printfWrapper("%s") //@diag("printfWrapper", "printf", "printfWrapper format %s reads arg #1, but call has 0 args")
|
||||
printfWrapper("%s") //@diag(re`printfWrapper\(.*\)`, "printf", "printfWrapper format %s reads arg #1, but call has 0 args")
|
||||
}
|
||||
|
||||
func printfWrapper(format string, args ...interface{}) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user