Skip to content

Commit 4174a4a

Browse files
authored
Merge pull request #197 from SVilgelm/selector-name
Add SelectorName in UncheckedError
2 parents ee08a45 + aeac866 commit 4174a4a

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

errcheck/errcheck.go

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ var (
6868

6969
// UncheckedError indicates the position of an unchecked error return.
7070
type UncheckedError struct {
71-
Pos token.Position
72-
Line string
73-
FuncName string
71+
Pos token.Position
72+
Line string
73+
FuncName string
74+
SelectorName string
7475
}
7576

7677
// Result is returned from the CheckPackage function, and holds all the errors
@@ -335,6 +336,37 @@ func (v *visitor) fullName(call *ast.CallExpr) string {
335336
return fn.FullName()
336337
}
337338

339+
func getSelectorName(sel *ast.SelectorExpr) string {
340+
if ident, ok := sel.X.(*ast.Ident); ok {
341+
return fmt.Sprintf("%s.%s", ident.Name, sel.Sel.Name)
342+
}
343+
if s, ok := sel.X.(*ast.SelectorExpr); ok {
344+
return fmt.Sprintf("%s.%s", getSelectorName(s), sel.Sel.Name)
345+
}
346+
347+
return ""
348+
}
349+
350+
// selectorName will return a name for a called function
351+
// if the function is the result of a selector. Otherwise it will return
352+
// the empty string.
353+
//
354+
// The name is fully qualified by the import path, possible type,
355+
// function/method name and pointer receiver.
356+
//
357+
// For example,
358+
// - for "fmt.Printf(...)" it will return "fmt.Printf"
359+
// - for "base64.StdEncoding.Decode(...)" it will return "base64.StdEncoding.Decode"
360+
// - for "myFunc()" it will return ""
361+
func (v *visitor) selectorName(call *ast.CallExpr) string {
362+
sel, _, ok := v.selectorAndFunc(call)
363+
if !ok {
364+
return ""
365+
}
366+
367+
return getSelectorName(sel)
368+
}
369+
338370
// namesForExcludeCheck will return a list of fully-qualified function names
339371
// from a function call that can be used to check against the exclusion list.
340372
//
@@ -531,11 +563,13 @@ func (v *visitor) addErrorAtPosition(position token.Pos, call *ast.CallExpr) {
531563
}
532564

533565
var name string
566+
var sel string
534567
if call != nil {
535568
name = v.fullName(call)
569+
sel = v.selectorName(call)
536570
}
537571

538-
v.errors = append(v.errors, UncheckedError{pos, line, name})
572+
v.errors = append(v.errors, UncheckedError{pos, line, name, sel})
539573
}
540574

541575
func readfile(filename string) []string {

errcheck/errcheck_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,8 @@ func test(t *testing.T, f flags) {
502502
if !uncheckedMarkers[m] && !blankMarkers[m] && !assertMarkers[m] {
503503
t.Errorf("%d: unexpected error: %v", i, err)
504504
}
505+
if err.SelectorName != "" && !strings.Contains(err.Line, err.SelectorName) {
506+
t.Errorf("the line '%s' must contain the selector '%s'", err.Line, err.SelectorName)
507+
}
505508
}
506509
}

0 commit comments

Comments
 (0)