summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev/revive/rule/time-naming.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mgechev/revive/rule/time-naming.go')
-rw-r--r--vendor/github.com/mgechev/revive/rule/time-naming.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/vendor/github.com/mgechev/revive/rule/time-naming.go b/vendor/github.com/mgechev/revive/rule/time-naming.go
new file mode 100644
index 0000000000..a93f4b5ae0
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/time-naming.go
@@ -0,0 +1,93 @@
+package rule
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "strings"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// TimeNamingRule lints given else constructs.
+type TimeNamingRule struct{}
+
+// Apply applies the rule to given file.
+func (r *TimeNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ w := &lintTimeNames{file, onFailure}
+
+ file.Pkg.TypeCheck()
+ ast.Walk(w, file.AST)
+ return failures
+}
+
+// Name returns the rule name.
+func (r *TimeNamingRule) Name() string {
+ return "time-naming"
+}
+
+type lintTimeNames struct {
+ file *lint.File
+ onFailure func(lint.Failure)
+}
+
+func (w *lintTimeNames) Visit(node ast.Node) ast.Visitor {
+ v, ok := node.(*ast.ValueSpec)
+ if !ok {
+ return w
+ }
+ for _, name := range v.Names {
+ origTyp := w.file.Pkg.TypeOf(name)
+ // Look for time.Duration or *time.Duration;
+ // the latter is common when using flag.Duration.
+ typ := origTyp
+ if pt, ok := typ.(*types.Pointer); ok {
+ typ = pt.Elem()
+ }
+ if !isNamedType(typ, "time", "Duration") {
+ continue
+ }
+ suffix := ""
+ for _, suf := range timeSuffixes {
+ if strings.HasSuffix(name.Name, suf) {
+ suffix = suf
+ break
+ }
+ }
+ if suffix == "" {
+ continue
+ }
+ w.onFailure(lint.Failure{
+ Category: "time",
+ Confidence: 0.9,
+ Node: v,
+ Failure: fmt.Sprintf("var %s is of type %v; don't use unit-specific suffix %q", name.Name, origTyp, suffix),
+ })
+ }
+ return w
+}
+
+// timeSuffixes is a list of name suffixes that imply a time unit.
+// This is not an exhaustive list.
+var timeSuffixes = []string{
+ "Sec", "Secs", "Seconds",
+ "Msec", "Msecs",
+ "Milli", "Millis", "Milliseconds",
+ "Usec", "Usecs", "Microseconds",
+ "MS", "Ms",
+}
+
+func isNamedType(typ types.Type, importPath, name string) bool {
+ n, ok := typ.(*types.Named)
+ if !ok {
+ return false
+ }
+ tn := n.Obj()
+ return tn != nil && tn.Pkg() != nil && tn.Pkg().Path() == importPath && tn.Name() == name
+}