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.

line-length-limit.go 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package rule
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "go/token"
  7. "strings"
  8. "unicode/utf8"
  9. "github.com/mgechev/revive/lint"
  10. )
  11. // LineLengthLimitRule lints given else constructs.
  12. type LineLengthLimitRule struct{}
  13. // Apply applies the rule to given file.
  14. func (r *LineLengthLimitRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure {
  15. if len(arguments) != 1 {
  16. panic(`invalid configuration for "line-length-limit"`)
  17. }
  18. max, ok := arguments[0].(int64) // Alt. non panicking version
  19. if !ok || max < 0 {
  20. panic(`invalid value passed as argument number to the "line-length-limit" rule`)
  21. }
  22. var failures []lint.Failure
  23. checker := lintLineLengthNum{
  24. max: int(max),
  25. file: file,
  26. onFailure: func(failure lint.Failure) {
  27. failures = append(failures, failure)
  28. },
  29. }
  30. checker.check()
  31. return failures
  32. }
  33. // Name returns the rule name.
  34. func (r *LineLengthLimitRule) Name() string {
  35. return "line-length-limit"
  36. }
  37. type lintLineLengthNum struct {
  38. max int
  39. file *lint.File
  40. onFailure func(lint.Failure)
  41. }
  42. func (r lintLineLengthNum) check() {
  43. f := bytes.NewReader(r.file.Content())
  44. spaces := strings.Repeat(" ", 4) // tab width = 4
  45. l := 1
  46. s := bufio.NewScanner(f)
  47. for s.Scan() {
  48. t := s.Text()
  49. t = strings.Replace(t, "\t", spaces, -1)
  50. c := utf8.RuneCountInString(t)
  51. if c > r.max {
  52. r.onFailure(lint.Failure{
  53. Category: "code-style",
  54. Position: lint.FailurePosition{
  55. // Offset not set; it is non-trivial, and doesn't appear to be needed.
  56. Start: token.Position{
  57. Filename: r.file.Name,
  58. Line: l,
  59. Column: 0,
  60. },
  61. End: token.Position{
  62. Filename: r.file.Name,
  63. Line: l,
  64. Column: c,
  65. },
  66. },
  67. Confidence: 1,
  68. Failure: fmt.Sprintf("line is %d characters, out of limit %d", c, r.max),
  69. })
  70. }
  71. l++
  72. }
  73. }