You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

call-to-gc.go 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package rule
  2. import (
  3. "go/ast"
  4. "github.com/mgechev/revive/lint"
  5. )
  6. // CallToGCRule lints calls to the garbage collector.
  7. type CallToGCRule struct{}
  8. // Apply applies the rule to given file.
  9. func (r *CallToGCRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
  10. var failures []lint.Failure
  11. onFailure := func(failure lint.Failure) {
  12. failures = append(failures, failure)
  13. }
  14. var gcTriggeringFunctions = map[string]map[string]bool{
  15. "runtime": map[string]bool{"GC": true},
  16. }
  17. w := lintCallToGC{onFailure, gcTriggeringFunctions}
  18. ast.Walk(w, file.AST)
  19. return failures
  20. }
  21. // Name returns the rule name.
  22. func (r *CallToGCRule) Name() string {
  23. return "call-to-gc"
  24. }
  25. type lintCallToGC struct {
  26. onFailure func(lint.Failure)
  27. gcTriggeringFunctions map[string]map[string]bool
  28. }
  29. func (w lintCallToGC) Visit(node ast.Node) ast.Visitor {
  30. ce, ok := node.(*ast.CallExpr)
  31. if !ok {
  32. return w // nothing to do, the node is not a call
  33. }
  34. fc, ok := ce.Fun.(*ast.SelectorExpr)
  35. if !ok {
  36. return nil // nothing to do, the call is not of the form pkg.func(...)
  37. }
  38. id, ok := fc.X.(*ast.Ident)
  39. if !ok {
  40. return nil // in case X is not an id (it should be!)
  41. }
  42. fn := fc.Sel.Name
  43. pkg := id.Name
  44. if !w.gcTriggeringFunctions[pkg][fn] {
  45. return nil // it isn't a call to a GC triggering function
  46. }
  47. w.onFailure(lint.Failure{
  48. Confidence: 1,
  49. Node: node,
  50. Category: "bad practice",
  51. Failure: "explicit call to the garbage collector",
  52. })
  53. return w
  54. }