Skip to content

Commit e604f91

Browse files
committed
analysis/report: better handling of sourcers with no node
Some IR values do not have a valid Source, most prominently constants. Don't panic when we can avoid it: when trying to emit related information, it makes more sense to drop the related information on the floor than to panic. We still panic for the toplevel diagnostic, because it makes no sense to print a diagnostic for an unknown location. It is an explicit panic now, however, so we get a more helpful message. Closes gh-972
1 parent 08e1523 commit e604f91

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

analysis/report/report.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package report
22

33
import (
44
"bytes"
5+
"fmt"
56
"go/ast"
67
"go/printer"
78
"go/token"
@@ -44,7 +45,10 @@ func Fixes(fixes ...analysis.SuggestedFix) Option {
4445

4546
func Related(node Positioner, message string) Option {
4647
return func(opts *Options) {
47-
pos, end := getRange(node, opts.ShortRange)
48+
pos, end, ok := getRange(node, opts.ShortRange)
49+
if !ok {
50+
return
51+
}
4852
r := analysis.RelatedInformation{
4953
Pos: pos,
5054
End: end,
@@ -126,21 +130,26 @@ func shortRange(node ast.Node) (pos, end token.Pos) {
126130
}
127131
}
128132

129-
func getRange(node Positioner, short bool) (pos, end token.Pos) {
130-
switch node := node.(type) {
133+
func getRange(node Positioner, short bool) (pos, end token.Pos, ok bool) {
134+
switch n := node.(type) {
131135
case sourcer:
132-
s := node.Source()
136+
s := n.Source()
137+
if s == nil {
138+
return 0, 0, false
139+
}
133140
if short {
134-
return shortRange(s)
141+
p, e := shortRange(s)
142+
return p, e, true
135143
}
136-
return s.Pos(), s.End()
144+
return s.Pos(), s.End(), true
137145
case fullPositioner:
138146
if short {
139-
return shortRange(node)
147+
p, e := shortRange(n)
148+
return p, e, true
140149
}
141-
return node.Pos(), node.End()
150+
return n.Pos(), n.End(), true
142151
default:
143-
return node.Pos(), token.NoPos
152+
return n.Pos(), token.NoPos, true
144153
}
145154
}
146155

@@ -158,7 +167,10 @@ func Report(pass *analysis.Pass, node Positioner, message string, opts ...Option
158167
}
159168
}
160169

161-
pos, end := getRange(node, cfg.ShortRange)
170+
pos, end, ok := getRange(node, cfg.ShortRange)
171+
if !ok {
172+
panic(fmt.Sprintf("no valid position for reporting node %v", node))
173+
}
162174
d := analysis.Diagnostic{
163175
Pos: pos,
164176
End: end,

0 commit comments

Comments
 (0)