Flag names of type time.Duration that have unit suffixes.
This catches people writing code such as
var timeoutSecs = 5 * time.Second
David Symonds
9 years ago
181 | 181 | f.lintMake() |
182 | 182 | f.lintErrorReturn() |
183 | 183 | f.lintUnexportedReturn() |
184 | f.lintTimeNames() | |
184 | 185 | } |
185 | 186 | |
186 | 187 | type link string |
259 | 260 | return nil |
260 | 261 | } |
261 | 262 | return p.typesInfo.TypeOf(expr) |
263 | } | |
264 | ||
265 | func (p *pkg) isNamedType(typ types.Type, importPath, name string) bool { | |
266 | n, ok := typ.(*types.Named) | |
267 | if !ok { | |
268 | return false | |
269 | } | |
270 | tn := n.Obj() | |
271 | return tn != nil && tn.Pkg() != nil && tn.Pkg().Path() == importPath && tn.Name() == name | |
262 | 272 | } |
263 | 273 | |
264 | 274 | // scopeOf returns the tightest scope encompassing id. |
1259 | 1269 | return true |
1260 | 1270 | } |
1261 | 1271 | |
1272 | // timeSuffixes is a list of name suffixes that imply a time unit. | |
1273 | // This is not an exhaustive list. | |
1274 | var timeSuffixes = []string{ | |
1275 | "Sec", "Secs", "Seconds", | |
1276 | "Msec", "Msecs", | |
1277 | "Milli", "Millis", "Milliseconds", | |
1278 | "Usec", "Usecs", "Microseconds", | |
1279 | "MS", "Ms", | |
1280 | } | |
1281 | ||
1282 | func (f *file) lintTimeNames() { | |
1283 | f.walk(func(node ast.Node) bool { | |
1284 | v, ok := node.(*ast.ValueSpec) | |
1285 | if !ok { | |
1286 | return true | |
1287 | } | |
1288 | for _, name := range v.Names { | |
1289 | origTyp := f.pkg.typeOf(name) | |
1290 | // Look for time.Duration or *time.Duration; | |
1291 | // the latter is common when using flag.Duration. | |
1292 | typ := origTyp | |
1293 | if pt, ok := typ.(*types.Pointer); ok { | |
1294 | typ = pt.Elem() | |
1295 | } | |
1296 | if !f.pkg.isNamedType(typ, "time", "Duration") { | |
1297 | continue | |
1298 | } | |
1299 | suffix := "" | |
1300 | for _, suf := range timeSuffixes { | |
1301 | if strings.HasSuffix(name.Name, suf) { | |
1302 | suffix = suf | |
1303 | break | |
1304 | } | |
1305 | } | |
1306 | if suffix == "" { | |
1307 | continue | |
1308 | } | |
1309 | f.errorf(v, 0.9, category("time"), "var %s is of type %v; don't use unit-specific suffix %q", name.Name, origTyp, suffix) | |
1310 | } | |
1311 | return true | |
1312 | }) | |
1313 | } | |
1314 | ||
1262 | 1315 | func receiverType(fn *ast.FuncDecl) string { |
1263 | 1316 | switch e := fn.Recv.List[0].Type.(type) { |
1264 | 1317 | case *ast.Ident: |